이 포스팅은 Youtube 'John Ahn'의 '따라하면서 배우는 NestJS'를 참고했습니다.
Nest js에서 파이프란 @Injectable() 데코레이터 주석이 달린 class를 말해요.
파이프는 클라이언트가 보내준 데이터에 대한 변형과 유효성체크를 위해서 사용됩니다.
미들웨어 같은 너낌..
파이프는 컨트롤러 경로 처리기에 의해 처리되는 인수에 대해 작동합니다.
Nest js는 메소드가 호출되기 직전에 파이프를 삽입하고, 파이프는 메소드로 향하는 인수를 수신하고 이에 대해 작동합니다.
예를 하나 들어볼게요.
board라는 게시물을 새로 생성하기 위해 클라이언트는 title과 description값을 서버로 보내줍니다.
이런 클라이언트가 보내준 데이터들이 컨트롤러에 가기 전에 한 단계를 거치게 되는데 이것을 Pipe라고 합니다.
Pipe에서 받아온 데이터를 원하는 형식으로 변환시키거나, 정해놓은 규칙에 맞는지 검사를 하고나서 이상이 없다면 컨트롤러에 전달해줘요.
만약 Int값이 와야 하는데 String type인 '7'이 왔다면 이에대해 정수값으로 변환해주거나, title값이 너무 길다 싶으면 에러를 내주는 역할 등을 하고 있어요.
파이프의 범위는 세 가지로 구분이 돼요.
@Post()
@UsePipes(pipe)
createBoard(@Body() createBoardDto: CreateBoardDto): Board {
return this.boardsService.createBoard(createBoardDto);
}
@Post()
createBoard(@Body('title', ParameterPipe) title,): Board {
return ...
}
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(GlobalPipes);
await app.listen(3000);
}
bootstrap();
당연히 파이프를 직접 만들어서 사용할 수도 있지만 Nest js에서는 친절하게도 기본적으로 사용할 수 있게끔 미리 만들어놓은 6가지 파이프가 있어요.
이름을 보면 그대로 기능을 유추할 수 있어요
이번에는 dto 파일에서 유효성 검사를 하고, createBoard() 라는 새로운 board 생성 method에서 Pipe를 적용해보겠습니다.
우선 손쉬운 validation을 지원해주는 라이브러리리 두개가 필요해요.
npm i class-validator class-transformer
설치 후, dto 파일로 가볼게요.
create-board.dto.ts
import { IsNotEmpty } from 'class-validator';
export class CreateBoardDto {
@IsNotEmpty()
title: string;
@IsNotEmpty()
desc: string;
}
@IsNotEmpty()로 클라이언트가 만약 빈값을 보내면 걸러줄 수 있도록 설정했어요.
이게 끝이 아니라 controller에서도 pipe를 적용해주어야 끝이나요.
boards.controller.ts
@Post()
@UsePipes(ValidationPipe)
createBoard(@Body() createBoardDto: CreateBoardDto): Board {
return this.boardsService.createBoard(createBoardDto);
}
@UsePipes를 통해서 ValidationPipe 를 지정해주면, dto에서 정해놓은 유효성검사 적용이 완료됩니다.
이번에는 Nest js 에서 제공하는 Pipe가 아닌 직접 Pipe를 만들어서 적용해볼게요.
파이프를 직접만들려면 PipeTransform이라는 인터페이스를 새롭게 만들 커스텀 파이프에 구현해주어야 해요.
이 PipeTransform 인터페이스는 모든 파이프에서 구현해주어야 하는 필수적인 인터페이스입니다.
그리고 이것과 함께, 모든 파이프에는 transform() method가 있어야 해요. 이 method는 Nest Js가 인자를 처리하기 위해서 사용됩니다.
즉, 파이프를 커스텀하려면
이 두개가 필수적으로 들어가야 해요.
import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';
@Injectable()
export class ValidationPipe implements PipeTransform {
transform(value: any, metadata: ArgumentMetadata) {
return value;
}
}
👀 transform () method
이 메소드는 두 개의 파라미터를 가지게 돼요.
첫번째로 value 라는 처리된 인자의 값과,
두번째로 인자에 대한 메타 데이터를 포함한 객체 입니다.
transform() 메소드에서 return 된 값은 route 핸들러로 전해지고, 만약 예외(Exception)이 발생한다면 코드를 멈추고 클라이언트에 바로 전해져요.
value는 처리된 인자값 이라고 표현을 했는데 그냥 클라이언트가 보내준 값이라고 생각하면 편할것 같아요.