Node.JS

NestJS Pipes 이용하기

5kiran 2023. 2. 10.
반응형

Pipes 란 무엇일까?

파이프는 @Injectable() 데코레이터로 주석이 달린 클래스입니다.

파이프는 data transformationdata validation을 위해서 사용됩니다.

 

data transformation ??

입력 데이터를 원하는 형식으로 변환 (string → number) (ex: "1" → 1)

숫자를 받아야 하는데 문자열로 온다면 파이프를 통해 자동으로 숫자로 바꿀 수 있습니다.

 

data validation ??

데이터가 올바르지 않을 때 에러를 발생시킵니다.

 

Pipe의 사용

파이프는 3가지의 사용법이 있습니다.

  1. Handler-level Pipes
  2. Parameter-level Pipes
  3. Global-level Pipes

Handler Pipes

이 파이프는 모든 파라미터 적용 됩니다.

@UsePipes()를 통해 사용합니다.

@Post
@UsePipes(pipes)
async createUser(
@Body('name') name,
@Body('password') password
) {

}

 

Parameter Pipes

특정한 파라미터에만 적용되는 파이프 입니다.

아래와 같은 경우 password에만  파이프가 적용됩니다.

@Post
async createUser(
@Body('name') name,
@Body('password', ParameterPipes) password
) {

}

 

Global Pipes

클라이언트에서 들어오는 모든 요청에 적용이 됩니다.

가장 상단의 영역인 main.ts에 들어갑니다.

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(GlobalPipes);
  await app.listen(3000);
}

 

Built-in Pipes

Nest JS에서는 기본적으로 사용할 수 있게 만들어 놓은 9가지 파이프가 있습니다.

사용법은 아래 공식문서 참조!

https://docs.nestjs.com/pipes

 

Documentation | NestJS - A progressive Node.js framework

Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Progamming), FP (Functional Programming), and FRP (Functional Reac...

docs.nestjs.com

 

파이프를 이용한 유효성 체크

필요한 모듈 설치

npm i class-validator class-transformer

 

 

기존 create.user.dto.ts

export class CreateUserDto {
  name : string
  password : string
}

 

변경 후 create.user.dto.ts

import { IsString } from "class-validator"

export class CreateUserDto {
  @IsString() //유효성 검사 데코레이터 @MinLength() @IsNotEmpty() 등이 있음
  name : string

  @IsString()
  password : string
}

자세한 사용법은 링크 참조 https://github.com/typestack/class-validator

 

GitHub - typestack/class-validator: Decorator-based property validation for classes.

Decorator-based property validation for classes. Contribute to typestack/class-validator development by creating an account on GitHub....

github.com

 

Handler Pipe를 적용한 Controller

import { Body, Controller, UsePipes, ValidationPipe } from '@nestjs/common';
import { Post } from '@nestjs/common/decorators';
import { CreateUserDto } from './dto/create.user.dto';
import { UsersService } from './users.service';

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Post()
  @UsePipes(ValidationPipe)
  createUser(@Body() data: CreateUserDto){
  
  }
}

 

Global Pipe를 적용한 main.ts

import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe({transform : true}));
  await app.listen(3000);
}
bootstrap();

 

커스텀 파이프를 이용한 유효성 체크

커스텀 파이프 만들기

먼저 PipeTransForm이란 인터페이스를 커스텀 파이프에 구현해줘야 합니다.

그리고 이것과 함께 모든 파이프는 transform() 메소드를 필요로 합니다.

transform() 메소드는 NestJS가 인자(arguments)를 처리하기 위해 사용됩니다.

 

user.name.validation.pipe.ts

import { BadRequestException } from '@nestjs/common/exceptions';
import { PipeTransform } from '@nestjs/common/interfaces';
import { CreateUserDto } from '../dto/create.user.dto';

export class UserNameValidationPipe implements PipeTransform {
  readonly nameOption = ['모찌', '만두'];
  transform(value: CreateUserDto) {
    const name = value.name;
    if (this.valueNameValid(name)) {
      throw new BadRequestException(`우리가 누구? xx,xx`);
    }
    return value;
  }

  private valueNameValid(name: string) {
    const index = this.nameOption.indexOf(name);
    return index === -1;
  }
}

 

커스텀 파이프 사용하기

import { Body, Controller } from '@nestjs/common';
import { Post } from '@nestjs/common/decorators';
import { CreateUserDto } from './dto/create.user.dto';
import { UserNameValidationPipe } from './pipes/user.name.validation.pipe';
import { UsersService } from './users.service';

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Post()
  async createUser(@Body(UserNameValidationPipe) data: CreateUserDto): Promise<string> {
    await this.usersService.createUser(data);

    return '가입 성공';
  }
}
반응형

'Node.JS' 카테고리의 다른 글

TypeORM queryRunner를 이용한 트랜잭션 제어  (0) 2023.02.15
NestJS TypeORM을 사용해보자  (0) 2023.02.14
Nest.js를 시작해보자  (0) 2023.02.09
Socket.io 송수신 메소드  (0) 2023.01.12
Express Cookie-Parser  (0) 2023.01.06

댓글