파이프는 @Injectable()
데코레이터 주석이 달린 클래스다. 파이프의 일반적인 사용 사례는 다음과 같다.
파이프는 클라이언트 요청에서 들어오는 데이터를 유효성 검사 및 변환을 수행하여 서버가 원하는 데이터를 얻을 수 있도록 도와주는 클래스다. 하나의 인풋이 들어오면 특정 로직을 걸쳐 아웃풋을 뱉는다. 아웃풋은 또 다음 함수로 들어가서 또 다시 아웃풋을 뱉는다. 각각의 함수들은 자신들의 자리에서 기능을 수행한 후 다음 함수에게 넘겨 주는 역할을 한다. 위 그림상에서 Task B가 필요없어진다면 바로 빼 버릴 수 있다. 이렇게 유지 보수가 편리하다는 장점이 있다.
입력 데이터를 원하는 형식으로 변환하는 '변환' 역할은 미들웨어와 비슷하게 보인다. 미들웨어도 요청과 응답에 변형을 가하는 동작을 한다. 단, 미들웨어는 현재 요청이 어떤 핸들러에서 수행되는지, 어떤 파라미터를 가지고 있는지에 대한 실행 컨텍스트를 알 수 없다. 이 차이점이 곧 파이프를 사용하는 목적과도 같다.
@Get(':id')
getOneCat(@Param() param) {
console.log(param); / { id: '243' }
return 'one cat';
}
http://localhost:3000/cats/243
로 요청을 보내면 console에 param 값으로 오브젝트 형식의 { id: '243' }
를 응답한다. 여기에 Param의 인자로 명확한 key값을 알려 주게 되면 파라미터는 id값의 value인 243을 뱉는다.
@Get(':id')
getOneCat(@Param('id') param) {
console.log(param); / 243
console.log(typeof param); / string
return 'one cat';
}
console에 찍힌 243의 타입은 string이다. 하지만 id 값은 string 보다 number로 사용하는 경우가 많다. string을 number로 바꿔 주는 역할을 파이프가 한다. 그때 사용할 수 있는 게 ParseIntPipe
이다.
@Get(':id')
getOneCat(@Param('id', ParseIntPipe) param: number) {
console.log(param); / 243
console.log(typeof param); / number
return 'one cat';
}
console에 찍힌 타입이 number로 변환된 것을 확인할 수 있다. 만약 동적 라우팅에 abc 같은, number로 변환될 수 없는 값으로 호출이 된다면 예외 처리 메시지(Validation)를 자동으로 띄워 준다.
import { Injectable, PipeTransform } from '@nestjs/common';
@Injectable()
export class PositiveIntPipe implements PipeTransform {
transform(value: number) {
return value;
}
}
이 파일의 transform()
함수가 위 그림의 Task다. 이 클래스를 @Param('id', ParseIntPipe, PositiveIntPipe)
에 적용시킬 수 있다. Task A는 ParseIntPipe
, Task B는 PositiveIntPipe
가 되는 것이다. A에서 나온 결과값은 B의 value로 들어간다. 예를 들어 2.2라는 값이 A를 지나면서 2로 변경되고 이 값을 B가 받는 것이다. 이렇게 파이프들을 쭉 타고 가다 보면 최종 결과값인 param을 받게 된다.
import { Injectable, PipeTransform, HttpException } from '@nestjs/common';
@Injectable()
export class PositiveIntPipe implements PipeTransform {
transform(value: number) {
if (value < 0) {
throw new HttpException('value가 0보다 작습니다.', 400);
}
return value;
}
}
이렇게 exception을 낼 수도 있다. http://localhost:3000/cats/-24.3
은 0보다 작다는 예외 처리에 걸려서 작성해 놓은 오류 코드를 낸다. 파이프는 이렇게 동작한다.