Контроллеры, DTO, ValidationPipe
↑ 6.2 NestJS · ← Предыдущая · → Следующая
Зачем это на собесе
Как принимаются и проверяются данные в Nest: DTO и class-validator.
Объяснение
export class CreateOrderDto {
@IsString() @IsNotEmpty() @MaxLength(100) customer: string;
@IsInt() @Min(1) @Max(1000) quantity: number;
@IsEmail() email: string;
@IsOptional() @IsEnum(Priority) priority?: Priority;
}
@Controller("orders")
export class OrdersController {
constructor(private readonly orders: OrdersService) {}
@Post()
@HttpCode(201)
create(@Body() dto: CreateOrderDto) { return this.orders.create(dto); }
@Get(":id")
find(@Param("id", ParseUUIDPipe) id: string) { return this.orders.find(id); }
@Get()
list(@Query() q: ListOrdersQuery) { return this.orders.list(q); }
}Глобальная валидация:
app.useGlobalPipes(new ValidationPipe({
whitelist: true, // убрать поля, не описанные в DTO
forbidNonWhitelisted: true, // 400 при лишних полях
transform: true, // приводить типы (строка → число) и создавать экземпляры DTO
}));DTO — классы, а не интерфейсы: интерфейсы стираются при компиляции, и декораторы class-validator работают только на классах. Альтернативы: Zod/Valibot с пайпом.
Нюансы и подводные камни
- Без
whitelistв объект попадают любые поля (mass assignment). - Вложенные объекты требуют
@ValidateNested()и@Type(() => Nested). - Query-параметры приходят строками: нужен
transform: trueилиParseIntPipe. - DTO для ответа тоже нужны: не отдавайте сущности БД (
ClassSerializerInterceptor). - Формат ошибок валидации стандартизируйте фильтром исключений.
Практика
- Опишите DTO создания и обновления (
PartialType) заказа. - Включите
whitelistи проверьте лишние поля. - Реализуйте валидацию вложенных позиций заказа.
Вопросы с ответами
Что делает ValidationPipe?
Проверяет входные данные по декораторам DTO и возвращает 400 при нарушении.
Зачем whitelist?
Отбрасывает или запрещает поля, не описанные в DTO, защищая от mass assignment.