Pipe는 입력 데이터가 라우트 핸들러에 도달하기 전에 변환하거나 검증하는 클래스입니다. controller 메서드의 인수에 작용하여 — 변환하거나(예: 문자열 → 숫자) 검증합니다(유효하지 않은 데이터 거부). NestJS의 검증은 pipe 위에 구축됩니다.
내장 변환 pipe
()
() {
..(id);
}
변환 pipe는 입력을 올바른 타입으로 변환하며(라우트 파라미터/쿼리는 항상 문자열), 변환이 불가능하면 400으로 실패합니다.
// main.ts에서 전역으로 활성화
app.useGlobalPipes(new ValidationPipe({
whitelist: true, // DTO에 선언되지 않은 속성 제거
forbidNonWhitelisted: true, // 알 수 없는 속성이 있으면 예외 발생
transform: true, // 일반 객체를 DTO 인스턴스로 변환, 타입 변환
}));
// class-validator decorator를 사용하는 DTO와 함께:
export class CreateUserDto {
@IsEmail() email: string;
@MinLength(8) password: string;
}
@Post()
create(@Body() dto: CreateUserDto) { // ValidationPipe가 본문을 자동 검증
// 유효하지 않으면 → 이것이 실행되기 전에 세부 정보가 담긴 400
}
ValidationPipe는 DTO의 class-validator decorator를 읽어 들어오는 데이터를 자동으로 검증합니다 — 실패 시 세부 정보가 담긴 400 오류를 반환하므로 핸들러는 항상 유효한 데이터만 받습니다.
요청 → ...middleware/guard/interceptor... → PIPE(변환/검증) → 핸들러
Pipe는 라우트 핸들러 바로 직전에 실행되며, 그 메서드 인수에 작용합니다.
@Injectable()
export class TrimPipe implements PipeTransform {
transform(value: any) {
return typeof value === "string" ? value.trim() : value; // 커스텀 변환
}
}
// 사용: @Body(TrimPipe) ...
커스텀 검증/변환 로직을 위해 PipeTransform의 transform() 메서드를 구현합니다.
@UsePipes(new ValidationPipe()) // 메서드 또는 controller 수준
@Param("id", ParseIntPipe) // 파라미터 수준
app.useGlobalPipes(new ValidationPipe()) // 전역 (검증에 가장 일반적)
Pipe는 입력을 안전하게 처리하는 핵심 NestJS 기능이며, 프레임워크 검증 시스템의 기초입니다.
거의 모든 API 엔드포인트가 입력을 검증하고 변환해야 하므로 이를 이해하는 것이 필수적입니다: 변환 pipe(ParseIntPipe 등)는 파라미터가 올바른 타입임을 보장하고, 가장 중요하게는 **ValidationPipe**가 DTO와 결합하여 요청 본문을 class-validator 규칙에 따라 자동으로, 선언적으로 검증하여 유효하지 않거나 악의적인 입력을 비즈니스 로직에 도달하기 전에 명확한 오류로 거부합니다.
이는 보안(신뢰할 수 없는 입력 검증/정제, 예상치 못한 속성 제거)과 견고성(핸들러가 유효한 데이터만 받음) 모두에 결정적입니다.
적절한 옵션(whitelist, transform)으로 전역 검증 pipe를 활성화하고, 내장 변환 pipe를 사용하고, 커스텀 pipe를 작성하는 방법을 아는 것은 안전하고 잘 구조화된 NestJS API를 구축하는 데 기본적입니다 — pipe와 검증은 프레임워크에서 일상적이고 반드시 알아야 할 개념입니다.