pipe

유석현(SeokHyun Yu)·2022년 12월 24일
0

Nest.js

목록 보기
8/9
post-thumbnail
post-custom-banner

1. 서론

pipe@Injectable() 데코레이터가 지정된 클래스로, PipeTransform 인터페이스를 implements 한 것이다.

pipe를 사용하는 이유는 2가지가 있다.

  • transformation(변환): 입력된 데이터를 원하는 형태로 변환한다(예: 문자열을 정수로).

  • validation(검증): 입력 데이터를 평가하고 유효한 경우 그대로 전달한다. 데이터가 잘못된 경우 예외를 발생시킨다.

Nest는 컨트롤러에 작성된 함수가 호출되기 전에 pipe를 삽입하고, pipe는 함수에 전달될 인수를 수신하고 이들을 처리한다.

Nest에는 즉시 사용할 수 있는 내장 pipe가 여러 개 있으며, 사용자 정의 pipe를 작성할 수도 있다.

먼저 내장 pipe부터 알아보자.


2. 내장 pipe

import { Controller, Get, Param } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get(':id')
  getHello(@Param('id') id: any) {
    
    return "hello"
  }
}

위 코드는 id를 param으로 받아서 사용하는 예이다.

id의 타입을 출력해보면 string 타입임을 알 수 있다.

import { Controller, Get, Param } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get(':id')
  getHello(@Param('id') id: any) {
    const type = typeof id;

    return { id, type };
  }
}


하지만 우리는 id를 string 타입이 아니라 number 타입으로 사용해야 될 수도 있다.

그럴때마다 우리가 직접 변환하는 것이 아니라 위에서 설명했던 pipe를 사용할 수 있다.

pipe를 사용하려면, pipe 클래스의 인스턴스를 적절한 컨텍스트에 바인딩해야 한다.

그럼 타입을 정수형으로 바꿔주는 ParseIntPipe 내장 pipe를 사용해보자.

import { Controller, Get, Param, ParseIntPipe } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get(':id')
  getHello(@Param('id', ParseIntPipe) id: any) {
    const type = typeof id;

    return { id, type };
  }
}

response를 보면 id가 number 타입으로 변환된 것을 볼 수 있다.

이것이 위에서 말했던 pipe를 사용하는 이유 중 하나인 "transformation"이다.

그렇다면 validation은 무엇일까?

다음 사진을 살펴보자.

":id" 값에 숫자가 아니라 알파벳을 입력했더니 400 에러가 발생했다.

이렇듯 숫자가 아닌 값을 id에 입력하면 자동으로 validation error를 발생시킨다.

이것이 pipe를 사용하는 두 번째 이유 "validation"이다.


3. 사용자 정의 pipe

그럼 이제 사용자가 정의하여 사용하는 pipe를 만들어보자

먼저 nest 명령어 nest g pipe {pipe 명} 으로 pipe 템플릿을 생성해주자.

다음과 같은 파일이 하나 생성되었을 것이다.

import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common';

@Injectable()
export class ParseStringPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    return value;
  }
}

위 클래스 안에 있는 transform() 함수가 바로 값을 변환하여 반환해주는 함수이다.

1번째 인자로 이전 값을 받아서 내부 로직을 거쳐 return 되면, 그 반환된 값이 바로 변환된 값이다.

그럼 위에서 ParseIntPipe를 통해 string 타입을 number 타입으로 바꿨으니 이번에는 number 타입을 string 타입으로 바꿔주는 pipe를 한 번 만들어보자.

import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common';

@Injectable()
export class ParseStringPipe implements PipeTransform {
  transform(value: number, metadata: ArgumentMetadata) {
    return `${value}`;
  }
}

그리고 컨트롤러에 이 pipe를 추가해주자.

import { ParseStringPipe } from './parse-string/parse-string.pipe';
import { Controller, Get, Param, ParseIntPipe } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get(':id')
  getHello(@Param('id', ParseIntPipe, ParseStringPipe) id: any) {
    const type = typeof id;

    return { id, type };
  }
}

그리고 response를 확인해보면 다음과 같다.

profile
Backend Engineer
post-custom-banner

0개의 댓글