NestJS Code Review Rules
Security (Critical)
- Validate all DTOs with
ValidationPipe - Use
@Exclude()to hide sensitive fields in responses - Implement rate limiting with
@nestjs/throttler - Sanitize user input before database queries to prevent injection attacks
- Never log sensitive data (passwords, tokens, API keys)
- Use parameterized queries or ORM methods to prevent SQL injection
- Avoid storing sensitive data or security-relevant instructions in HTML comments
Module Architecture
- One module per feature/domain
- Modules should export only what other modules need
- Use
forRoot/forRootAsyncfor configurable modules - Avoid circular dependencies between modules
Controllers
- Keep controllers thin (delegate to services)
- Use DTOs for request validation, not raw objects
- Apply guards at controller or handler level as appropriate
- Use proper HTTP status codes with
@HttpCode() - Follow RESTful conventions for resource naming
- Use consistent routing structure (e.g.,
/api/v1/resources) - Implement API versioning when needed
- Use descriptive route paths and parameter names
Services
- Services contain business logic
- Use constructor injection for dependencies
- Services should be stateless (no instance variables for request data)
- Use
@Injectable()with appropriate scope (default singleton is usually correct) - Use
async/awaitfor asynchronous operations - Avoid unhandled promise rejections - always handle errors
- Propagate errors appropriately (don't swallow exceptions)
- Return meaningful error messages from service layer
DTOs and Validation
- Use
class-validatordecorators on DTO properties - Apply
ValidationPipeglobally or per-route - Use
class-transformerfor type transformation - Create separate DTOs for create/update operations
Guards and Interceptors
- Guards for authentication/authorization
- Interceptors for logging, transformation, caching
- Use
@UseGuards()and@UseInterceptors()decorators - Order matters: guards run before interceptors
Error Handling
- Use built-in exceptions (
NotFoundException,BadRequestException, etc.) - Create exception filters for custom error formatting
- Don't catch and ignore errors silently
Configuration (Essential)
- Use
@nestjs/configfor configuration management - Validate environment variables on startup
- Use
ConfigModule.forRoot()in app module - Access config via
ConfigServicedependency injection - Don't hardcode configuration values in code
Testing
- Write unit tests using
@nestjs/testing - Mock dependencies with
createMockor manual mocks - Test controllers, services, and guards separately
- Use
Test.createTestingModule()for integration tests - Write e2e tests for critical flows
- Separate test code from implementation code
File Organization
- Follow consistent file naming (e.g.,
user.controller.ts,user.service.ts) - Group related files in feature folders
- Keep modules, controllers, services, DTOs in separate files
- Use consistent folder structure across features
- Place shared/common code in dedicated folders
API Documentation (Advanced)
- Use
@nestjs/swaggerfor automatic API documentation - Apply
@Api*decorators to controllers and DTOs - Document all endpoints with
@ApiOperation() - Define response types with
@ApiResponse() - Include examples in
@ApiProperty()decorators - Keep Swagger docs up to date with code changes