Version: 1.0.15
@bunet/core
is an open-source library designed to build robust applications with the support of performance monitoring tools like OpenTelemetry. This library simplifies the integration, monitoring, and scaling of systems, ensuring efficiency and reliability for developers.
- Easy Integration: Supports popular tools such as OpenTelemetry and Sequelize.
- Performance Monitoring: Tracks metrics and traces to analyze system performance.
- Modular Codebase: Easy to maintain and extend.
- TypeScript Support: Ensures type safety and code clarity.
- Comprehensive Testing Tools: Includes test cases to ensure code quality.
@bunet/core
employs Dependency Injection (DI) to enhance flexibility and scalability. DI decouples the creation of system components, making the codebase easier to test and manage.
- Improved Reusability: Components are separated and easily reusable.
- Enhanced Testability: DI allows easy mocking of components during testing.
- Reduced Tight Coupling: Minimizes module dependencies, improving scalability.
@bunet/core
implements DI through the following steps:
- Register Services and Modules: Services are declared and registered in a central container.
- Inject Dependencies During Initialization: Services automatically receive their dependencies when used.
Example:
// Declare and register services
import { DbContext, DbSet } from '@/bunet/core';
import { Options, Sequelize } from 'sequelize';
import { UserModel } from './Aggregates/UserAggregate/User';
export class AppDbContext extends DbContext {
public Users: DbSet<UserModel> = new DbSet<UserModel>(UserModel.Definition(this.sequelize, 'User', 'Users'));
constructor(options: Options) {
super(options);
}
protected OnModelCreating(sequelize: Sequelize): void {
this.sequelize.sync({ alter: true }).catch(console.error);
}
}
export class UserService {
@Inject() private context!: AppDbContext;
async create(user: IUser): Promise<UserModel> {
return this.context.Users.Create(user);
}
}
// Initialize the container and register services
const builder = WebApplication.CreateBuilder();
const services = builder.Services;
services.AddControllers().AddDbContext(
DbContext.OnConfiguring(AppDbContext, {
dialect: 'postgres',
host: 'localhost',
port: 5433,
username: 'postgres',
password: 'postgres',
database: 'postgres',
})
);
// Use DI to inject dependencies
services.AddSingleton(UserService.name, UserService);
In this example, UserService
automatically receives an instance of AppDbContext
without needing to instantiate it directly. This simplifies dependency management and increases flexibility.
├── global.d.ts # TypeScript global definitions
├── package.json # Project metadata and dependencies
├── tsconfig.json # TypeScript configuration file
├── src/ # Source code of the project
├── test/ # Unit tests
- Node.js: Version >= 14.0.0
- npm: Version >= 6.0.0
To install @bunet/core
, run the following command:
npm install @bunet/core
import 'global.d.ts';
import { WebApplication } from '@/bunet/core';
const builder = WebApplication.CreateBuilder();
const app = builder.Build(__dirname);
app.Run(3000);
import 'global.d.ts';
import { DbContext, WebApplication } from '@/bunet/core';
import { AppDbContext } from './Database/AppDbContext';
import { UserService } from './Services/UserService';
const builder = WebApplication.CreateBuilder();
const services = builder.Services;
services.AddOpenTelemetry({
protocol: 'http',
host: 'localhost',
port: 80,
systemMetricsInterval: 6000,
});
const app = builder.Build(__dirname);
app.Run(3000);
export class AppDbContext extends DbContext {
public Users: DbSet<UserModel> = new DbSet<UserModel>(UserModel.Definition(this.sequelize, 'User', 'Users'));
constructor(options: Options) {
super(options);
}
protected OnModelCreating(sequelize: Sequelize): void {
this.sequelize.sync({ alter: true }).catch(console.error);
}
}
export interface IUser {
id: string;
name: string;
userName: string;
password: string;
}
export interface IUserCreationAttributes extends Optional<IUser, 'id'> {}
export class UserModel extends Model<IUser, IUserCreationAttributes> {
static Definition(sequelize: Sequelize, modelName: string, tableName: string): typeof UserModel {
UserModel.init(
{
id: {
type: DataTypes.STRING(32),
defaultValue: (): string => {
return uuidv7(true);
},
primaryKey: true,
},
name: {
type: DataTypes.STRING,
allowNull: false,
},
userName: {
type: DataTypes.STRING,
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
},
{
sequelize,
modelName,
tableName,
timestamps: true,
hooks: {
beforeCreate: (user) => {
console.log(`Creating user`, user.get({ plain: true }));
},
afterCreate: (user) => {
console.log(`User created`);
},
},
}
);
return UserModel;
}
}
npm test
Test cases are located in the test/
directory. Example:
const assert = require('assert');
describe('Sample Test', () => {
it('should return true', () => {
assert.strictEqual(true, true);
});
});
This library uses the following dependencies:
@opentelemetry/api
: ^1.9.0@opentelemetry/exporter-prometheus
: ^0.57.0@opentelemetry/instrumentation-http
: ^0.57.0@opentelemetry/sdk-metrics
: ^1.30.0@opentelemetry/sdk-node
: ^0.57.0@opentelemetry/sdk-trace-base
: ^1.30.0@opentelemetry/sdk-trace-node
: ^1.30.0pg
: ^8.13.1reflect-metadata
: ^0.2.2sequelize
: ^6.37.5
We welcome contributions from the community! To contribute:
- Fork the repository.
- Create a new branch:
git checkout -b feature/your-feature-name
- Commit your changes:
git commit -m "Add a new feature"
- Push your branch:
git push origin feature/your-feature-name
- Create a pull request.
Fullname: Dao Khoi Nguyen
Contact: [email protected]
LinkedIn: https://www.linkedin.com/in/khoinguyenict
This project is licensed under the MIT License.