Що таке pipes у NestJS?
Pipes в NestJS
Pipes перетворюють і валідують вхідні дані перед тим, як вони потраплять до обробника маршруту. Вони реалізують інтерфейс PipeTransform і працюють з аргументами, переданими до методу контролера.
Pipes мають два основних випадки використання:
- Валідація — валідувати і викидати помилку, якщо недійсні
- Перетворення — конвертувати дані в інший тип
Вбудовані Pipes
| Pipe | Призначення |
|---|---|
ValidationPipe | Валідація з використанням class-validator / DTOs |
ParseIntPipe | Конвертувати рядок в ціле число |
ParseFloatPipe | Конвертувати рядок в число з плаваючою комою |
ParseBoolPipe | Конвертувати рядок в булевий тип |
ParseArrayPipe | Парсити значення масиву |
ParseUUIDPipe | Валідація формату UUID |
ParseEnumPipe | Валідація проти значень enum |
DefaultValuePipe | Надати значення за замовчуванням |
Використання вбудованих Pipes
typescript
@Get(':id')
findOne(@Param('id', ParseIntPipe) id: number) {
// id вже є числом, ніколи не рядком!
return this.usersService.findOne(id);
}
// З кастомним статусом помилки
@Get(':id')
findOne(
@Param('id', new ParseIntPipe({ errorHttpStatusCode: HttpStatus.NOT_ACCEPTABLE }))
id: number
) { ... }
// ParseUUIDPipe
@Get(':uuid')
findOne(@Param('uuid', ParseUUIDPipe) uuid: string) { ... }
// DefaultValuePipe
@Get()
findAll(
@Query('page', new DefaultValuePipe(1), ParseIntPipe) page: number,
@Query('limit', new DefaultValuePipe(10), ParseIntPipe) limit: number,
) { ... }Кастомний Pipe
typescript
import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
@Injectable()
export class PositiveIntPipe implements PipeTransform<string, number> {
transform(value: string, metadata: ArgumentMetadata): number {
const num = parseInt(value, 10);
if (isNaN(num)) {
throw new BadRequestException(`${metadata.data} must be a number`);
}
if (num <= 0) {
throw new BadRequestException(`${metadata.data} must be positive`);
}
return num;
}
}
// Використання:
@Get(':id')
findOne(@Param('id', PositiveIntPipe) id: number) { ... }Validation Pipe (Найважливіший)
typescript
// Глобальний — застосовується до всіх маршрутів
app.useGlobalPipes(new ValidationPipe({
whitelist: true, // видалити невідомі властивості
forbidNonWhitelisted: true, // помилка на невідомі властивості
transform: true, // автоматичне перетворення типів
transformOptions: {
enableImplicitConversion: true, // рядок '1' → число 1
},
errorHttpStatusCode: HttpStatus.UNPROCESSABLE_ENTITY, // 422 замість 400
}));
// Перевизначення на рівні маршруту
@Post()
@UsePipes(new ValidationPipe({ whitelist: true }))
create(@Body() dto: CreateUserDto) { ... }Рівні прив'язки Pipe
typescript
// Рівень параметра (найбільш специфічний)
@Get(':id')
findOne(@Param('id', ParseIntPipe) id: number) {}
// Рівень методу
@Post()
@UsePipes(ValidationPipe)
create(@Body() dto: CreateUserDto) {}
// Рівень контролера
@Controller('users')
@UsePipes(new ValidationPipe())
export class UsersController {}
// Глобальний (в main.ts або через APP_PIPE)
app.useGlobalPipes(new ValidationPipe());
// або:
{ provide: APP_PIPE, useClass: ValidationPipe }Парсинг масивів запитів
typescript
@Get()
findAll(
@Query('ids', new ParseArrayPipe({ items: Number, separator: ',' }))
ids: number[]
) {
// GET /users?ids=1,2,3 → ids = [1, 2, 3]
return this.usersService.findByIds(ids);
}Підсумок
Pipes є шаром обробки даних NestJS. Завжди використовуйте ValidationPipe глобально з whitelist: true та transform: true. Використовуйте ParseIntPipe, ParseUUIDPipe тощо для приведення типів параметрів URL/запиту. Створюйте кастомні pipes для специфічної логіки валідації домену.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.