CodingNeed.

3 · Reliability and delivery · 30 MIN

Nest DTOs and validation pipes

DTO classes describe runtime validation through decorators.

A TypeScript interface disappears at runtime, so Nest’s decorator-based validation uses DTO classes. ValidationPipe applies those rules at the application boundary. whitelist removes properties without validation decorators, while forbidNonWhitelisted rejects those fields instead of silently stripping them. Decorators from class-validator enforce length and string type. Transformation and coercion should be deliberate: automatically converting arbitrary strings to numbers can obscure the accepted wire format.

Enable the pipe before listening.

Read the example

// npm install class-validator class-transformer
// preview.dto.ts
import {IsString,Length} from 'class-validator';
export class PreviewDto {@IsString() @Length(3,80) title!:string}
// preview.controller.ts
import {Body,Controller,Post} from '@nestjs/common';
import {PreviewDto} from './preview.dto';
@Controller('preview') export class PreviewController {@Post() preview(@Body() body:PreviewDto){return {preview:body.title}}}
// In main.ts, before await app.listen(...):
// import {ValidationPipe} from '@nestjs/common';
// app.useGlobalPipes(new ValidationPipe({whitelist:true,forbidNonWhitelisted:true}));
Check the expected output
With the controller registered and pipe enabled, valid input succeeds and unknown or invalid fields return 400.

Your challenge

Add a bounded integer weeklyGoal field and test missing values, numeric strings and extra fields against an explicit wire contract.

Solution cost: O(f) validation for f fields, plus string-length work. time · O(f) DTO representation. space

Common trap

Decorators alone do nothing if the application never runs a validation pipe.

Study the project implementation
// npm install class-validator class-transformer
// preview.dto.ts
import {IsString,Length} from 'class-validator';
export class PreviewDto {@IsString() @Length(3,80) title!:string}
// preview.controller.ts
import {Body,Controller,Post} from '@nestjs/common';
import {PreviewDto} from './preview.dto';
@Controller('preview') export class PreviewController {@Post() preview(@Body() body:PreviewDto){return {preview:body.title}}}
// In main.ts, before await app.listen(...):
// import {ValidationPipe} from '@nestjs/common';
// app.useGlobalPipes(new ValidationPipe({whitelist:true,forbidNonWhitelisted:true}));

Further reading: Official documentation

Next lesson: Project · Pagination with a stable contract

Essential cookies keep your account signed in. Optional analytics is not configured on this site. Your choice does not affect access to lessons.

Read the Privacy Policy. You can change this choice in the footer.