In NestJS, we typically use classes and decorators to define DTOs (Data Transfer Objects) to ensure the data types and structure of API requests are correct. To automatically add type validation decorators to DTOs, we can leverage the class-validator library, which provides various decorators for data validation. Here are the steps and examples for implementation:
Step 1: Install Dependencies
First, install class-validator and class-transformer. These libraries enable automatic validation and transformation of class properties at runtime.
bashnpm install class-validator class-transformer
Step 2: Create DTO Class and Add Decorators
Within the DTO class, use decorators from class-validator to define validation rules. For example, to validate data for a user registration endpoint, create a UserDTO class as follows:
typescriptimport { IsNotEmpty, IsEmail, Length } from 'class-validator'; export class UserDTO { @IsNotEmpty({ message: 'Username cannot be empty' }) username: string; @IsEmail({}, { message: 'Please provide a valid email address' }) email: string; @IsNotEmpty({ message: 'Password cannot be empty' }) @Length(8, 20, { message: 'Password length must be between 8 and 20 characters' }) password: string; }
Step 3: Use DTO in Controller
In the controller, use the @Body() decorator to receive the request body and specify the DTO type. NestJS automatically applies the validation rules defined in the DTO.
typescriptimport { Controller, Post, Body } from '@nestjs/common'; import { UserDTO } from './dto/user.dto'; @Controller('users') export class UserController { @Post('register') async register(@Body() userDto: UserDTO) { // Here, userDto has already been validated return 'User registered'; } }
Step 4: Enable Global Validation Pipe
To enable NestJS to handle validation decorators in DTOs, activate the global validation pipe in your application. Add the following configuration in your main module or bootstrap file:
typescriptimport { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { ValidationPipe } from '@nestjs/common'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.useGlobalPipes(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true })); await app.listen(3000); } bootstrap();
Conclusion
By using class-validator and class-transformer, you can easily add type validation decorators to DTO classes in your NestJS application. This approach simplifies data validation implementation and maintains code cleanliness and consistency. If validation fails, NestJS automatically throws exceptions and returns client-specific error messages, significantly improving development efficiency and making the code easier to maintain and test.