[Nest] Nest WikiDocs (4.11) (2)

ShinJuYong·2022년 4월 11일
0

Nest

목록 보기
5/13
post-thumbnail

(1) 에서 이어짐.

파이프

요청이 Router로 전달되기전, 요청에대한 객체를 변환하는 로직을 제공한다

나중에 볼 미들웨어와 비슷한 역할
하지만 미들웨어는 App의 모든 Context에서 사용이 불가능하지만 파이프는 가능하다.

파이프의 사용 목적

  • Transform : 입력 데이터를 원하는 형식으로 바꾼다
    ex) /users/user/1의 파라미터인 1을 정수로 변환
  • Validation : 입력 데이터를 서버가 정한 기준에 유효하지 않는경우 예외 처리를 시켜줌

유효성 검사 파이프 만들어보기

유효성 검사에 쓰이는 라이브러리를 먼저 설치하자
yarn add class-validator
yarn add class-transformer

신규 유저를 생성할때 (CreateUser) 본문이 유효한지 테스트.

createUser.dto.ts

import { IsEmail, IsString, MaxLength, MinLength } from 'class-validator';

export class CreateUserDto {
  @IsString()
  @MinLength(1)
  @MaxLength(20)
  name: string;

  @IsEmail()
  email: string;
  readonly password: string;
}

이제 위에서 정의한 dto객체를 받아서 유효성을 검증하는 파이프를 구현하자.

import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { validate } from 'class-validator';
import { plainToClass } from 'class-transformer';

@Injectable()
export class ValidationPipe implements PipeTransform<any> {
  async transform(value: any, { metatype }: ArgumentMetadata) {
    if (!metatype || !this.toValidate(metatype)) {
      return value;
    }
    const object = plainToClass(metatype, value);
    const errors = await validate(object);
    if (errors.length > 0) {
      throw new BadRequestException('Validation failed');
    }
    return value;
  }

  private toValidate(metatype: Function): boolean {
    const types: Function[] = [String, Boolean, Number, Array, Object];
    return !types.includes(metatype);
  }
}
  1. 전달된 metatype이 파이프가 지원하는 타입인지 검사한다.
  2. class-transformer의 plainToClass를 통해 순수 자바스크립트 객체를 Class의 객체로 바꿔준다.
  3. 마지막으로 유효성 검사를 통과했다면 원래의 값을 전달해준다.
  4. 실패시에는 400 BadRequest에러를 던져준다.

이 Pipe를 그대로 컨트롤러에 적용한다.
users.controller.ts

  @Post()
  async createUser(@Body(ValidationPipe) dto: CreateUserDto): Promise<void> {
    const { name, email, password } = dto;
    await this.usersService.createUser(name, email, password);
  }

전역설정하는법.

main.ts

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

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

bootstrap을 만드는과정중에 globalpipes로 넣게되면 전역으로 설정된다.

0개의 댓글