| name | nestjs |
| description | Best practices and coding standards for NestJS framework development. Domain-centric architecture, dependency injection, decorator pattern utilization. TRIGGER: NestJS project, @Module/@Controller/@Injectable decorator, REST/GraphQL API development, dependency injection pattern |
NestJS Development Standards
Module Organization Principles
Domain-Centric Modularization
Organize modules by business domain, not by function.
- ❌ Bad:
controllers/,services/,repositories/ - ✅ Good:
users/,products/,orders/
Single Responsibility Module
Each module is responsible for only one domain.
- Separate common functionality into
common/orshared/modules - Inter-domain communication must go through Services only
Dependency Injection Rules
Constructor Injection Only
Property injection (@Inject) is forbidden.
// ✅ Good
constructor(private readonly userService: UserService) {}
// ❌ Bad
@Inject() userService: UserService;
Provider Registration Location
Providers are registered only in the module where they are used.
- Minimize global providers
- Use forRoot/forRootAsync only in AppModule
Decorator Usage Rules
Prioritize Custom Decorators
Abstract repeated decorator combinations into custom decorators.
// Create custom decorator when combining 3+ decorators
@Auth() // Integrates @UseGuards + @ApiBearerAuth + @CurrentUser
Decorator Order
Arrange in execution order from top to bottom.
- Metadata decorators (@ApiTags, @Controller, @Resolver)
- Guards/Interceptors (@UseGuards, @UseInterceptors)
- Route decorators (@Get, @Post, @Query, @Mutation)
- Parameter decorators (@Body, @Param, @Args)
DTO/Entity Rules
DTO is Pure Data Transfer
Business logic is forbidden; only validation is allowed.
// ✅ Good: Validation only
class CreateUserDto {
@IsEmail()
email: string;
}
// ❌ Bad: Contains business logic
class CreateUserDto {
toEntity(): User {} // Forbidden
}
Separate Entity and DTO
Never return Entity directly; always convert to DTO.
- Request: CreateInput, UpdateInput (GraphQL) / CreateDto, UpdateDto (REST)
- Response: Type definition or plain object
Error Handling
Domain-Specific Exception Filter
Each domain has its own Exception Filter.
@Module({
providers: [
{
provide: APP_FILTER,
useClass: UserExceptionFilter,
},
],
})
Explicit Error Throwing
Always throw Exception explicitly in all error situations.
- REST: Use HttpException series
- GraphQL: Use GraphQLError or custom error
- Forbid implicit null/undefined returns
- Error messages should be understandable by users