Modules
The Bueno module system provides a NestJS-inspired dependency injection container with decorators. It's ideal for larger applications that benefit from clear separation of concerns and testable, injectable services.
Creating a module
import { Module, Controller, Injectable, Get, Post } from '@buenojs/bueno/modules';
@Injectable()
class UserService {
private users = [{ id: 1, name: 'Alice' }];
findAll() {
return this.users;
}
findById(id: number) {
return this.users.find(u => u.id === id);
}
}
@Controller('/api/users')
class UserController {
constructor(private userService: UserService) {}
@Get('/')
list() {
return this.userService.findAll();
}
@Get('/:id')
get(ctx: Context) {
const user = this.userService.findById(Number(ctx.params.id));
if (!user) return ctx.notFound();
return ctx.json(user);
}
}
@Module({
controllers: [UserController],
providers: [UserService],
})
class UserModule {}
Bootstrapping
import { createApp } from '@buenojs/bueno/modules';
const app = createApp();
app.registerModule(UserModule);
await app.listen(3000);
Decorators
Class decorators
Decorator
Purpose
@Module(meta)
Declares a module
@Controller(prefix)
Declares a controller with a route prefix
@Injectable()
Marks a class as injectable
Method decorators
Decorator
HTTP Method
@Get(path)
GET
@Post(path)
POST
@Put(path)
PUT
@Patch(path)
PATCH
@Delete(path)
DELETE
Parameter decorators
@Get('/:id')
get(@Param('id') id: string, @Query('verbose') verbose: string) {
// ...
}
@Post('/')
create(@Body() body: CreateUserDto) {
// ...
}
Guards
Guards run before a handler and can block access:
@Injectable()
class AuthGuard implements CanActivate {
canActivate(ctx: Context): boolean | Promise<boolean> {
return !!ctx.getHeader('Authorization');
}
}
@Controller('/api/admin')
@UseGuards(AuthGuard)
class AdminController {
// All routes require auth
}
Interceptors
Intercept the handler execution — useful for logging, caching, and response transformation:
@Injectable()
class LoggingInterceptor implements NestInterceptor {
async intercept(ctx: Context, next: CallHandler) {
const start = Date.now();
const result = await next.handle();
console.log(`Duration: ${Date.now() - start}ms`);
return result;
}
}
Lifecycle hooks
@Injectable()
class DatabaseService implements OnModuleInit, OnApplicationBootstrap {
async onModuleInit() {
await this.connect();
}
async onApplicationBootstrap() {
await this.runMigrations();
}
}
Module structure
For larger applications, organize modules by feature:
src/
├── app.module.ts
├── users/
│ ├── user.module.ts
│ ├── user.controller.ts
│ ├── user.service.ts
│ └── user.entity.ts
└── posts/
├── post.module.ts
├── post.controller.ts
└── post.service.ts
Importing modules
@Module({
imports: [UserModule, PostModule],
controllers: [AppController],
})
class AppModule {}
Providers exported from UserModule become available to AppModule's controllers and providers.
Released under the MIT License. Built with love by the Bueno Community.