Skip to main content

Валідація DTO

Щоб автоматично валідувати DTO в NestJS за допомогою class-validator, зроби 4 кроки:

1) Постав пакети

javascript
npm i class-validator class-transformer

2) Визнач DTO з декораторами

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; }

Для вкладених об'єктів/масивів використовуй @ValidateNested() + @Type(() => Class) з class-transformer.

3) Увімкни глобальний ValidationPipe (один раз у 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 за типами DTO whitelist: true, // видаляє поля, яких немає в DTO forbidNonWhitelisted: true, // кидає 400, якщо передано зайві поля stopAtFirstError: false, // зібрати всі помилки (чи true - перша помилка) transformOptions: { enableImplicitConversion: true }, // прості авто-конверсії })); await app.listen(3000); } bootstrap();

Можна застосовувати пайп локально: @Post() create(@Body(new ValidationPipe()) dto: CreateUserDto) { … }, але зазвичай зручніше глобально.

4) Використовуй DTO в контролері

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) { // сюди потрапить уже ПРОВАЛІДОВАНИЙ і ПЕРЕТВОРЕНИЙ об'єкт return { ok: true, dto }; } }

Корисні прийоми

  • Вкладені DTO

    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[]; }
  • Часткове оновлення (PATCH) Використовуй хелпери з @nestjs/mapped-types:

    javascript
    import { PartialType } from '@nestjs/mapped-types'; export class UpdateUserDto extends PartialType(CreateUserDto) {}
  • Кастомні повідомлення й локалізація

    javascript
    @Length(3, 50, { message: "Ім'я має бути від 3 до 50 символів" })
  • Своя форма помилки У ValidationPipe можна задати exceptionFactory, щоб повернути потрібну структуру відповіді:

    javascript
    new ValidationPipe({ exceptionFactory: (errors) => new BadRequestException({ errors }) })
  • Групи валідації (різні правила для create/update)

    javascript
    @IsString({ groups: ['create'] }) // pipe: new ValidationPipe({ groups: ['create'] })
  • Опціональні поля Завжди додавай @IsOptional() поруч із валідаторами, якщо поле необов'язкове.

Резюме

  1. DTO з декораторами class-validator.
  2. Глобальний ValidationPipe з transform, whitelist, forbidNonWhitelisted.
  3. Використання DTO в сигнатурах контролерів.
  4. Для вкладених структур - ValidateNested + @Type.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.