개발일지

Nest.js 커스텀 파이프

index.ys 2023. 12. 30. 16:03

Nest.js 커스텀 파이프

customPipe.pipe.ts

  • 파이프는 PipeTransform 에서 구현해야 하는 메서드를 명시함
  • transform메서드의 value는 실제로 변환하거나 검증할 값
  • metadata는 ArgumentMetadata 인터페이스 형태의 메타데이터 객체, value에 대한 정보를 포함함 => 타입, 파라미터
  • 커스텀 파이프를 작성하기 위한 가장 기본적인 형태, transform 메서드에 들어온 value를 조작하여 검증 및 변환 가능
import { Injectable, PipeTransform, ArgumentMetadata } from '@nestjs/common';

@Injectable()
export class CustomPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {

    return 반환할 값
  }
}

Pipe-transform

  • pipetransform.interface.d.ts에 정의된 PiepeTransform 인터페이스
  • PipeTransform은 두개의 제네릭 타입 매개변수를 가짐
  • T는 파이프가 받는 입력 값의 타입
  • R은 파이프가 반환하는 결과의 타입
  • transform 메서드는 파이프에서 구현해야하는 핵심 메서드
export interface PipeTransform<T = any, R = any> {
    /**
     * Method to implement a custom pipe.  Called with two parameters
     *
     * @param value argument before it is received by route handler method
     * @param metadata contains metadata about the value
     */
    transform(value: T, metadata: ArgumentMetadata): R;
}

ArgumentMetadata

  • ArgumentMeatadata 인터페이스 정의
  • type : 파라미터의 타입을 나타냄
  • metatype : 파라미터가 string으로 정의 되었다면 string이라는 타입정의, 선택적 정의 (옵셔널 체이닝 ?)이므로 정의되지 않는 경우도 잇음
  • data: 전달된 문자열을 나타냄
export interface ArgumentMetadata {
    /**
     * Indicates whether argument is a body, query, param, or custom parameter
     */
    readonly type: Paramtype;
    /**
     * Underlying base type (e.g., `String`) of the parameter, based on the type
     * definition in the route handler.
     */
    readonly metatype?: Type<any> | undefined;
    /**
     * String passed as an argument to the decorator.
     * Example: `@Body('userId')` would yield `userId`
     */
    readonly data?: string | undefined;
}

커스텀 파이프 작성

  • 전달된 value를 대문자로 변환하는 파이프
import { Injectable, PipeTransform, ArgumentMetadata } from '@nestjs/common';

@Injectable()
export class  UppercasePipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {

	if(value.length <= 0 )
       throw new BadRequestException('입력된 값이 없습니다.')
      }
  
 
  return  value.toUpperCase();
}

Postcontroller에 UppercasePipe추가하기

  @Post()
  postsPosts(
    @Body('authorId') authorId: number,
    //Body로 전달되는 title의 값을 전부 대문자로 변환함
    @Body('title', UppercasePipe) title: string,
    @Body('content') content: string,
  ) {
    // create => 저장할 객체를 생성한다.
    // save => 객체를 저장한다 , create메서드에서 생성한 객체로
    console.log(title);
    return this.postService.createPost(authorId, title, content);
  }
  • 요청 Body

  • 콘솔에 찍힌 값
  • 대문자로 입력을 했으나 UppercasePipe로 인해 문자가 전부 대문자로 변경되어 라우터 핸들러로 전달됨

기타

  • Pipe를 일반화 시켜 여러 핸들러에서 사용하거나 다른 Pipe와 중복으로 사용할 수 있음
  • Pipe를 중복으로 사용하여 전달된 값에 대한 검증과 변환가능
  @Post()
  postsPosts(
    @Body('authorId') authorId: number,
    @Body('title', UppercasePipe, IsStringPipe) title: string,
    @Body('content') content: string,
  ) {