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