In NestJS, class validation can be implemented using the class-validator and class-transformer packages. The following outlines the steps to validate a class's properties and nested objects with these tools:
Install Required Packages
First, install class-validator and class-transformer using npm or yarn.
bashnpm install class-validator class-transformer # or yarn add class-validator class-transformer
Create DTO (Data Transfer Object) Classes
In NestJS, DTO (Data Transfer Object) classes are commonly created to define the structure of incoming data and apply validation rules.
typescriptimport { IsString, IsInt, ValidateNested, IsEmail } from 'class-validator'; import { Type } from 'class-transformer'; class UserDto { @IsString() readonly name: string; @IsEmail() readonly email: string; @IsInt() readonly age: number; } class CreateUserDto { @ValidateNested({ each: true }) @Type(() => UserDto) readonly user: UserDto; }
In this example, CreateUserDto contains a nested UserDto object. The @ValidateNested() decorator specifies that the property is a nested object requiring validation. The @Type(() => UserDto) decorator from class-transformer instructs NestJS on how to convert raw data into a UserDto instance.
Use DTOs in Controllers
In controllers, DTO classes are used to receive and validate client-sent data.
typescriptimport { Body, Controller, Post } from '@nestjs/common'; import { CreateUserDto } from './create-user.dto'; @Controller('users') export class UsersController { @Post() async create(@Body() createUserDto: CreateUserDto) { // createUserDto is now validated and an instance of CreateUserDto // Implement user creation logic here } }
Enable Global Validation Pipe
To enable automatic validation with class-validator, configure NestJS's global validation pipe. This can be set up in the root module or main.ts.
typescriptimport { ValidationPipe } from '@nestjs/common'; import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.useGlobalPipes(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true, transform: true, })); await app.listen(3000); } bootstrap();
In this configuration, whitelist: true automatically strips non-whitelisted properties (those not defined in the DTO), and forbidNonWhitelisted: true throws an error when such properties are received. The transform option automatically converts raw client data into DTO instances.
Error Handling
If input data violates validation rules defined in the DTO class, NestJS throws an exception. Typically, this is caught by a global exception filter and returns an error response to the client. Custom error messages can be implemented with a dedicated exception filter.
By following these steps, class validation and nested object validation can be implemented in a NestJS application. This approach ensures concise and robust data validation, guaranteeing data correctness and validity before business logic execution.