[Nest.js] Pipe 타입 변환, 유효성 검사

Woong·2022년 12월 15일
0

Nestjs

목록 보기
14/28

Pipe

개요

  • pipe 는 타입 변환(trasform)과 유효성 검사(validataion) 2가지를 수행한다.

    • transform : string 을 number 로 변환하는 등 입력 데이터를 원하는 형태로 변환
    • validation : 입력 데이터가 유효한지 검사하고, 유효하지 않을 경우 exception 발생
  • controller 의 route handler 에서 동작한다.

적용

  • 파이프는 route handler 메소드의 파라미터에서 적용할 수 있다.
@Get(':id')
async findOne(@Param('id', ParseIntPipe) id: number) {
  return this.catsService.findOne(id);
}
@Get(':uuid')
async findOne(@Param('uuid', new ParseUUIDPipe()) uuid: string) {
  return this.catsService.findOne(uuid);
}

Built-in 파이프

  • Nest.js 에는 아래 9개의 내장 파이프가 존재한다.
ValidationPipe
ParseIntPipe
ParseFloatPipe
ParseBoolPipe
ParseArrayPipe
ParseUUIDPipe
ParseEnumPipe
DefaultValuePipe
ParseFilePipe

커스텀 파이프

  • PipeTransform<T,R> 인터페이스를 구현하여 파이프 정의
    • T 는 input, R 은 return 타입
import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';

@Injectable()
export class PositiveIntPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    if (value < 0) {
      throw new Exception('value < 0', 400)
    }
    return value;
  }
}

고급 유효성 검사

  • 기본 pipe 를 통한 검사 외에도 보다 상세한 유효성 검사를 할 수 있다.

설치

  • class-validator, class-transformer 설치한다.
    • npm i --save class-validator class-transformer

바인딩

  • 전체 애플리케이션 레벨에서 ValidataionPipe 를 바인딩하여 전체 엔드포인트 보호
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(3000);
}
bootstrap();
  • 메소드 레벨에 바인딩
@Post()
@UsePipes(new ValidationPipe({ transform: true }))
async create(@Body() createCatDto: CreateCatDto) {
  this.catsService.create(createCatDto);
}

검사

  • class-validator 에 정의된 데코레이터를 통해 검사
    • 검사에서 통과하지 못할 경우 400 error 발생
import { IsEmail, IsNotEmpty, IsNumberString } from 'class-validator';

export class CreateUserDto {
  @IsEmail()
  email: string;

  @IsNotEmpty()
  password: string;
  
  @IsNumberString()
  age: number;
}

화이트리스트

  • 정의하지 않은 프로퍼티를 받지 않도록 필터링
    • 기본적으론 dto 에서 정의하지 않아도 input 으로 받을 수 있지만
    • whitelist: true 로 하면 정의되지 않은 것들은 제거 후 받음
    • forbidNonWhitelisted 을 true 로 설정시 정의되지 않은 내용이 있으면 exception 발생
app.useGlobalPipes(
  new ValidationPipe({
    whitelist: true,
  }),
);

reference

0개의 댓글