Validation Pipes: class-validator, class-transformer Transformation Pipeline
- Last updated
- Prerequisites:
- TypeScript decorators
- DTO (Data Transfer Object) pattern
- nestjs
- pipes
- validation-pipe
- class-validator
- class-transformer
- dto
Read at your depth
The practical view
Pipes in NestJS serve two purposes: **Transformation** (converting input data to the desired type, like `ParseIntPipe`) and **Validation** (verifying incoming request body against a DTO class using `ValidationPipe`). By decorating DTO fields with `class-validator` annotations (`@IsString()`, `@IsEmail()`, `@Min(18)`), `ValidationPipe` automatically validates and converts JSON payloads, throwing a `400 Bad Request` with structured error details on failure.
The same idea in other frameworks
`@UsePipes(new ValidationPipe({ whitelist: true }))` with `class-validator` DTOs.Pydantic v2 `BaseModel` schema validation and automatic coercion.Spring Boot `@Valid` / `@Validated` with Hibernate Validator annotations (`@NotNull`, `@Email`).Zod or Joi schema validation middleware.Legacy vs modern
Manual Request Body Validation vs Automatic ValidationPipe
Manual validation in every controller is error-prone and insecure; `ValidationPipe` strips unknown properties and enforces DTO contracts.
if (!body.email || !body.email.includes('@')) throw new BadRequestException(); // ❌ Fragileexport class CreateUserDto { @IsEmail() email: string; @Min(18) age: number; } // ✅ NEWInterview gotchas
Context
Interviewers test your knowledge of mass-assignment vulnerabilities in REST APIs.
The mechanical answer
By default, `plainToInstance` leaves un-declared properties attached to the request object. If an attacker sends `{ "email": "user@test.com", "role": "admin", "balance": 99999 }`, those extra fields could be passed directly to the database. Setting `whitelist: true` **silently strips all un-declared properties** not decorated with validation annotations. Setting `forbidNonWhitelisted: true` **rejects the request immediately with a 400 error** if any unknown property is present.
Trap
Any DTO property lacking a `class-validator` decorator will be stripped if `whitelist: true` is enabled.
Context
Checks knowledge of type coercion in NestJS pipes.
The mechanical answer
All HTTP URL route parameters (e.g. `/users/:id`) and query parameters (`?page=1`) arrive as JavaScript `string` primitives. With `transform: true`, `ValidationPipe` automatically converts these strings into their declared TypeScript primitive types (`number`, `boolean`) or instantiates complex DTO class instances using `class-transformer`.
Trap
Without `transform: true`, `@Param('id') id: number` will actually contain a `string` at runtime, causing strict equality checks (`id === 123`) to fail.