Suggest an editImprove this articleRefine the answer for “DTO validation”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)Install `class-validator` and `class-transformer`, describe the DTO with decorators (`@IsString()`, `@IsEmail()`, etc.), enable a global `ValidationPipe` in `main.ts` with `transform`/`whitelist`/`forbidNonWhitelisted`, and use the DTO as the type for a `@Body()` parameter in the controller - Nest then validates and transforms the incoming data automatically. **Key point:** nested objects/arrays need `@ValidateNested()` + `@Type(() => Class)` from `class-transformer`; for PATCH it's convenient to derive `PartialType(CreateUserDto)` from `@nestjs/mapped-types`, and a custom error shape is set via `exceptionFactory` on the `ValidationPipe`.Shown above the full answer for quick recall.Answer (EN)ImageTo **automatically validate a DTO** in NestJS with **class-validator**, follow 4 steps: ## 1) Install the packages ```javascript npm i class-validator class-transformer ``` ## 2) Define the DTO with decorators ```javascript // dto/create-user.dto.ts import { IsEmail, IsString, Length, IsOptional, IsInt, Min } from 'class-validator'; export class CreateUserDto { @IsString() @Length(3, 50) name: string; @IsEmail() email: string; @IsOptional() @IsInt() @Min(0) age?: number; } ``` > For nested objects/arrays, use `@ValidateNested()` + `@Type(() => Class)` from `class-transformer`. ## 3) Enable a global ValidationPipe (once, in `main.ts`) ```javascript // main.ts import { 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({ transform: true, // string → number/boolean based on the DTO's types whitelist: true, // strips fields not present in the DTO forbidNonWhitelisted: true, // throws a 400 if extra fields are sent stopAtFirstError: false, // collect every error (or true for just the first) transformOptions: { enableImplicitConversion: true }, // simple auto-conversions })); await app.listen(3000); } bootstrap(); ``` > The pipe can be applied locally: > `@Post() create(@Body(new ValidationPipe()) dto: CreateUserDto) { … }`, > but it's usually more convenient **globally**. ## 4) Use the DTO in the controller ```javascript // users.controller.ts import { Body, Controller, Post } from '@nestjs/common'; import { CreateUserDto } from './dto/create-user.dto'; @Controller('users') export class UsersController { @Post() create(@Body() dto: CreateUserDto) { // by this point the object is already VALIDATED and TRANSFORMED return { ok: true, dto }; } } ``` ## Useful techniques - **Nested DTOs** ```javascript import { ValidateNested, IsArray } from 'class-validator'; import { Type } from 'class-transformer'; class AddressDto { @IsString() city: string; } class CreateUserDto { @ValidateNested() @Type(() => AddressDto) address: AddressDto; @IsArray() @ValidateNested({ each: true }) @Type(() => AddressDto) previousAddresses: AddressDto[]; } ``` - **Partial updates (PATCH)** Use the helpers from `@nestjs/mapped-types`: ```javascript import { PartialType } from '@nestjs/mapped-types'; export class UpdateUserDto extends PartialType(CreateUserDto) {} ``` - **Custom messages and localization** ```javascript @Length(3, 50, { message: 'Name must be between 3 and 50 characters' }) ``` - **A custom error shape** `ValidationPipe` accepts an `exceptionFactory` to return the response shape you want: ```javascript new ValidationPipe({ exceptionFactory: (errors) => new BadRequestException({ errors }) }) ``` - **Validation groups** (different rules for create/update) ```javascript @IsString({ groups: ['create'] }) // pipe: new ValidationPipe({ groups: ['create'] }) ``` - **Optional fields** Always add `@IsOptional()` alongside the validators when a field isn't required. ### Summary 1. A DTO with `class-validator` decorators. 2. A global `ValidationPipe` with `transform`, `whitelist`, `forbidNonWhitelisted`. 3. Using the DTO in controller signatures. 4. For nested structures, `ValidateNested` + `@Type`.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.