Installing Dependencies
First, ensure the necessary dependency packages are installed:
npm install class-validator class-transformerConfiguring Global Pipeline
You can configure the global ValidationPipe in your main.ts or app.module.ts file:
// main.ts
import { NestFactory } from '@nestjs/core';
import { ValidationPipe } from '@nestjs/common';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// Configure ValidationPipe globally
app.useGlobalPipes(
new ValidationPipe({
// Automatically validate incoming data
whitelist: true, // Strip unneeded properties
forbidNonWhitelisted: true, // Prohibit undeclared properties
transform: true, // Transform payload objects
transformOptions: {
enableImplicitConversion: true, // Enable explicit conversion
},
forbidUnknownValues: true, // Prohibit unknown values
errorHttpStatusCode: 400, // Error status code
disableErrorMessages: true, // Disable detailed error messages
}),
);
await app.listen(3000);
}
bootstrap();Creating DTO Class
Define a DTO (Data Transfer Object) class to represent the structure of your request body:
// src/users/dto/create-user.dto.ts
import { IsEmail, IsNotEmpty, MaxLength, MinLength } from 'class-validator';
export class CreateUserDto {
@IsEmail()
email: string;
@IsNotEmpty()
@MinLength(8)
@MaxLength(20)
password: string;
}Using DTO Class
Use the DTO class in a controller to validate and transform the request body:
// src/users/users.controller.ts
import { Controller, Post, Body } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
@Controller('users')
export class UsersController {
@Post()
async createUser(@Body() createUserDto: CreateUserDto) {
// Since ValidationPipe has validated the data, createUserDto is safe and transformed
console.log(createUserDto);
// Here you can call a service method to save the user
}
}Mapping Types
If you need to map the DTO type to another type, you can perform the conversion in the service layer:
// src/users/users.service.ts
import { Injectable } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
@Injectable()
export class UsersService {
async createUser(createUserDto: CreateUserDto) {
// Map the DTO to another type here
const user = {
email: createUserDto.email,
password: createUserDto.password,
// Add other fields
};
// Save the user
}
}Parsing and Validating Arrays
To validate and parse arrays, you can use the Array type in the DTO:
// src/users/dto/create-user.dto.ts
import { IsEmail, IsNotEmpty, ValidateNested, ArrayMaxSize, ArrayMinSize } from 'class-validator';
import { Type } from 'class-transformer';
export class CreateUserDto {
@IsEmail()
email: string;
@IsNotEmpty()
@MinLength(8)
@MaxLength(20)
password: string;
@ArrayMinSize(1)
@ArrayMaxSize(5)
@ValidateNested({ each: true })
@Type(() => TagDto)
tags: TagDto[];
}
export class TagDto {
@IsNotEmpty()
name: string;
}Using Array DTO in Controller
You can use the array DTO in a controller like this:
// src/users/users.controller.ts
import { Controller, Post, Body } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
@Controller('users')
export class UsersController {
@Post()
async createUser(@Body() createUserDto: CreateUserDto) {
console.log(createUserDto);
}
}- Automatic Validation: By using
ValidationPipe, you can automatically validate incoming data against the rules defined in the DTO. - Disabling Detailed Errors: Setting
disableErrorMessagestotrueprevents detailed error messages from being returned to the client, which is beneficial for security. - Stripping Performance: Setting
whitelisttotrueensures only properties declared in the DTO are retained, improving performance and reducing memory usage. - Transforming Payload Objects: Setting
transformtotrueallowsValidationPipeto convert incoming objects to the DTO type, eliminating the need for manual conversion. - Explicit Conversion: Setting
transformOptions.enableImplicitConversiontotrueenables implicit conversions, such as converting strings to numbers.



