Що таке dto та як працює валідація в NestJS?
DTO та валідація в NestJS
DTO (Об'єкт передачі даних) — це клас, який визначає структуру даних, що надходять у вашу програму. У поєднанні з class-validator та class-transformer, NestJS забезпечує потужну, декларативну валідацію запитів.
Налаштування
bash
npm install class-validator class-transformerУвімкніть глобальний ValidationPipe у main.ts:
typescript
import { ValidationPipe } from '@nestjs/common';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe({
whitelist: true, // видалити невідомі властивості
forbidNonWhitelisted: true, // викинути помилку, якщо надіслані невідомі властивості
transform: true, // автоматично перетворювати типи (рядок → число)
}));
await app.listen(3000);
}Створення DTO
typescript
// dto/create-user.dto.ts
import {
IsString, IsEmail, IsOptional, IsInt,
MinLength, MaxLength, Min, Max, IsEnum
} from 'class-validator';
export enum UserRole {
USER = 'user',
ADMIN = 'admin',
}
export class CreateUserDto {
@IsString()
@MinLength(2)
@MaxLength(50)
name: string;
@IsEmail()
email: string;
@IsOptional()
@IsInt()
@Min(18)
@Max(120)
age?: number;
@IsOptional()
@IsEnum(UserRole)
role?: UserRole = UserRole.USER;
}Використання DTO в контролері
typescript
@Controller('users')
export class UsersController {
@Post()
create(@Body() createUserDto: CreateUserDto) {
// Валідація відбувається автоматично!
// Якщо недійсно → 400 Bad Request з деталями
return this.usersService.create(createUserDto);
}
}Відповідь на помилку валідації
Коли валідація не проходить, NestJS автоматично повертає:
json
{
"statusCode": 400,
"message": [
"email must be an email",
"name must be longer than or equal to 2 characters"
],
"error": "Bad Request"
}Оновлення DTO з PartialType
typescript
// dto/update-user.dto.ts
import { PartialType } from '@nestjs/mapped-types';
import { CreateUserDto } from './create-user.dto';
// Всі поля з CreateUserDto стають необов'язковими
export class UpdateUserDto extends PartialType(CreateUserDto) {}Вкладені DTO
typescript
import { Type } from 'class-transformer';
import { ValidateNested, IsArray } from 'class-validator';
export class AddressDto {
@IsString() street: string;
@IsString() city: string;
}
export class CreateUserDto {
@IsString() name: string;
@ValidateNested()
@Type(() => AddressDto)
address: AddressDto;
@IsArray()
@ValidateNested({ each: true })
@Type(() => AddressDto)
previousAddresses: AddressDto[];
}Користувацький декоратор валідації
typescript
import { registerDecorator, ValidationOptions } from 'class-validator';
export function IsSlug(validationOptions?: ValidationOptions) {
return (object: object, propertyName: string) => {
registerDecorator({
name: 'isSlug',
target: object.constructor,
propertyName,
options: validationOptions,
validator: {
validate(value: unknown) {
return typeof value === 'string' && /^[a-z0-9-]+$/.test(value);
},
defaultMessage: () => '$property must be a valid slug',
},
});
};
}Підсумок
DTO з декораторами class-validator забезпечують декларативну, автоматичну валідацію запитів у NestJS. Увімкніть ValidationPipe глобально з whitelist: true та transform: true для кращої безпеки. Використовуйте PartialType для DTO оновлення та ValidateNested для складних вкладених об'єктів.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.