Node.js

[NestJs]Pipe사용하기

무서운승태 2023. 12. 26. 20:14
728x90

 

Pipe란????

다음은 NestJs에서 요청과 응답의 흐름을 나타낸다. controller전에 4번을 보면 pipes라고 있는 것을 확인할 수 있다.

  • 파이프(pipe)란??
    • 엔드포인트에 도달하기 전 요청 데이터에 대해 유효성 검증을 할 수 있다.
    • 요청 데이터에 대해 변환 작업을 할 수 있다.

 

 @Get(':id')
    getPost(@Param('id') id: string) {
        return this.postsService.getPostById(+id);
    }

다음과 같이 id를 통해 게시글을 조회하는 로직이 있다. 현재는 url에서 string으로 id를 받기 때문에 +를 이용하여 number타입으로 형변환을 해주었다. 우리는 서버에서 id는 항상 number를 사용할 것이기 때문에 넘어올 때부터 number로 일괄적으로 바꿔줄 수 있다.

 

 @Get(':id')
    getPost(@Param('id', ParseIntPipe) id: number) {
        return this.postsService.getPostById(id);
    }

PaseIntPipe Class를 붙여주면 id를 int로 변환해서 전달된다. 우리는 형변환 없이 id를 사용할 수 있다.nest에서 제공하는 pipe의 종류는 다음과 같다.

이것 외 내가 원하는 대로 pipe를 만들어서 사용할수있다. 회원가입 시 비밀번호를 8자리 이하로 제한하는 파이프를 만들어보자.

 

파이프 직접 만들기

1. 파이프 폴터를 만들고 타입스크립트 파일을 만든다.

 

2. 파이프를 만들 때는 반드시 다음과 같이 import를 해주어야 한다.

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

 

3. class를 만들고 Injectable을 붙여주고 implements 키워드로 PipeTranform을 구현해 준다.

@Injectable()
export class passwordPipe implements PipeTransform {
    transform(value: any, metadata: ArgumentMetadata) {
        if (value.toString().length > 8) {
            throw new BadRequestException('비밀번호는 8자 이하로 입력해주세요');
        }

        return value.toString();
    }
}
  • transform 함수를 필수로 구현해야 하며 실질적인 로직이 여기에 들어가게 된다.
  • value는 요청에서 넘어온 실질적인 데이터를 뜻한다.(여기서는 password)
  • metadata는 각종 정보가 담겨 있다.
    • type : 파리미터 타입 ex) query, param, body.... 
    • metatype : 컨트롤러에서 받는 타입 ex) id: string => string을 말함
    • data : key값을 의미함 ex) @Param('id') => id를 말함

4. 생성자를 만들어주면 로직을 좀 더 일반화시킬 수 있다.(사용 시 new 키워드를 통해 인자값 넘기기)

@Injectable()
export class MaxLengthPipe implements PipeTransform {
	constructor (
    	private readonly maxLength: number
    ) {
    }
    
    transform(value: any, metadata: ArgumentMetadata) {
        if (value.toString().length > this.maxLength) {
            throw new BadRequestException('비밀번호는 8자 이하로 입력해주세요');
        }

        return value.toString();
    }
}

 

  @Post('register/email')
    registerEmail(
        @Body('email') email: string,
        @Body('password', new MaxLengthPipe(10)) password: string,
        @Body('nickname') nickname: string,
    ) {
        return this.authService.registerWithEmail({
            email,
            password,
            nickname,
        });
    }