NestJs - Pipes
NestJs - 파이프
Pipes
파이프는 Injectable
데코레이터를 통해 의존성이 주입되고, PipeTransform
인터페이스를 구현하는 클래스 객체이다. 파이프는 ClientSide에서 보낸 요청이 Route Handler(Controller)에 도달하기 전(Controller 앞단)에 동작하여 요청에 포함된 Body, Param의 데이터를 검증하거나, 형변환을 시킨다.
Pipe에는 보편적으로 2가지 UseCase가 있다.
Transformation(형변환)
- Input 데이터의 타입(형)을 변환한다.
- ex) String형을 Integer형으로 변경
Validation(데이터 검증)
- Input 데이터를 검증하여 조건에 부합하지 않는 경우, 예외를 발생시킨다.
- ex) 입력된 데이터의 Max가 5인데 6이 입력되었을 시, 해당 요청은 예외 처리된다.
Pipes 동작 방식
파이프는 Route Handler(Controller)에서 처리되는 arguments
에 대해 동작한다. Nest는 Route Handler의 메소드가 호출되기 직전에 파이프를 추가하고, 파이프는 해당 메소드가 받게될 arguments
를 인자로 받아 형변환 및 데이터 검증 작업을 실행한다. 해당 작업이 끝나면 Route Handler의 호출된 메소드가 실행된다.
Bult-in Pipes
Nest는 기본적으로 9가지 Pipes를 @nestjs/common
패키지에 내장하고 있다.
Validation Pipes
ParseIntPipe
ParseFloatPipe
ParseBoolPipe
ParseArrayPipe
ParseUUIDPipe
ParseEnumPipe
DefaultValuePipe
ParseFilePipe
Binding Pipes
파이프를 사용하기 위해서는 Pipe 클래스의 인스턴스를 정상적인 context에 바인딩 시켜야한다. Route Handler의 메소드에 내부 Param 데코레이터의 param 키 값 뒤에 사용하거나, 새로 Pipe 클래스를 초기화하여 생성자에 custom한 errorHttpStatusCode를 주입할 수 있다.
@Get(':id')
async findOne(@Param('id', ParseIntPipe) id: number) {
return this.catsService.findOne(id);
}
@Get(':id')
async findOne(
@Param('id', new ParseIntPipe({ errorHttpStatusCode: HttpStatus.NOT_ACCEPTABLE }))
id: number,
) {
return this.catsService.findOne(id);
}
Global Pipes
파이프는 전역적으로 설정하여 서버 애플리케이션 전체 Route Handler에 해당 pipe를 추가할 수 있다.
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe());
await app.listen(8000);
}
bootstrap();
하지만 GateWay나 MicroServices를 사용하는 경우, useGlobalPipes
를 통해 파이프를 전역적으로 설정할 수 없어서 AppModule(혹은 서버 애플리케이션의 의존성을 관리하는 Module)단에서 따로 Providers에 추가해줘야한다.
import { Module } from '@nestjs/common';
import { APP_PIPE } from '@nestjs/core';
@Module({
providers: [
{
provide: APP_PIPE,
useClass: ValidationPipe,
},
],
})
export class AppModule {}