[Nest.js 정리] Pipe
Pipes란
공식문서 https://docs.nestjs.com/pipes
쉽게 말하면 받아오는 값들의 형태를 바꾸고 유효성검증까지 해주는 기능을 제공하는 도구라고 생각하면 된다. 기본으로 제공하는 종류는 공식문서를 참고해보자.
pipes는 잘못된 요청 (‘asda’와 같은 string을 parseIntPipe를 거친다면 에러 반환)에 대한 대응력 강화 (= 타입 관리 용이)
pipes를 기본적으로 제공하는 것 외에도 커스텀하여 활용할 수 있다.
Custom Pipe
만약 password의 길이가 8 글자로 제한이 되어야 하는 상황이라면? pipe를 만들어서 제한할 수 있다!
pipe 파일 만들기
pipe는 Injectable이며 PipeTransform을 implements 해야한다. (docs)
1
2
3
4
5
6
7
8
9
10
11
12
import {PipeTransform, Injectable, ArgumentMetadata, BadRequestException} from '@nestjs/common'
// 모든 Pipe는 Injectable이며, PipeTransform 을 implements해야한다. (docs 확인)
@Injectable()
export class PasswordPipe implements PipeTransform {
transform(value: any, metadata: ArgumentMetadata) {
if (value.toString().length > 8) {
throw new BadRequestException('Password must have at least 8 characters')
}
return value.toString();
}
};
따라서 이와 같은 구조를 지닌다. 이 파일의 의미는 value를 받고, 그 value의 길이가 일정 길이 이상이라면 오류를 반환하고 아니라면 string으로 전환하여 되돌려 주겠다~ 는 의미이다.
다음과 같은 결과로 정상작동함을 확인할 수 있다.
근데 ArgumentMetadata
는 무엇인가
사실 pipe를 custom 할 땐 value의 type이 중요하지 해당 값은 중요하지 않다.
근데 궁금해서 알아보았다. 쉽게말해 데이터의 출처가 어디이고 (Param, Query, Body) 그 타입은 무엇이며 (String, Number ..) 어떤값을 지니고 있는가를 의미하는 것.
pipe 사용 심화
매번 custom 하는게 낭비인 경우가 있을 수 있다. 작은 pipe들을 조합해서 이 여러개를 사용할 수 있을까? 또 숫자만 달라지는 경우 숫자에 맞춰 계속 만들어야할까?
다음과 같은 과정으로 수치를 주입하고 여러개의 Pipe를 동시에 사용할 수 있다. 글자수를 몇글자부터 몇글자까지 제한하는 pipe생성과정을 알아보자.
construcor … 의 과정으로 값을 주입할 수 있도록 한다.
이런식으로 활용할 수 있다! 일반화된 pipe를 생성하고 이를 활용하여 custom Pipe를 활용할 수 있다.
또 여기서 의문이 들 수 있다. 위에선 class를 그냥 넣었는데, 왜 이 값은 인스턴스를 만들어서 넣었는지. 일반적으론 그냥 class 넣는것이 권장된다. Nest가 내부적으로 인스턴스를 관리하는 것으로 효율적이다. 하지만 파이프에 특별한 설정을 하는 경우 (커스텀) 직접 인스턴스를 생성하고 사용할 수 있다.