DTO, validation

설명
Data Transfer Object
Tags
 

DTO란?

Data Transfer Object로, 영어 그대로 데이터를 전송하는 오브젝트를 뜻함.
사용자가 보냈으면 하는 데이터 형식을 DTO로 정의하고, API 인풋의 타입으로 활용한다.

예시

export class CreateMovieDto { readonly title: string; readonly year: number; readonly genres: string[]; }
MovieDTO 선언
... @Post() create(@Body() movieData: CreateMovieDto) { // movieData의 타입은 CreateMovieDto 이라는 뜻 return this.moviesService.create(movieData); } ...
Body의 movieData의 타입을 설정함
MovieData를 만들 때 사용자로부터 받았으면 하는 데이터와 타입을 명시하였다.
하지만 사용자는 이 형식대로 보내지 않아도 된다.
여기서 우리가 설정한 DTO 형식대로 validation까지 되면 더 좋을 거 같다는 생각이 든다.
 

Validation 추가

필요 라이브러리 설치

# validation을 위한 라이브러리 설치 $ yarn add class-validator class-transformer
 

main.ts에 유효성 검사를 위한 파이프 추가

파이프는 미들웨어라고 생각하면 된다.
유효성 검사를 위한 파이프인 ValidationPipe를 추가한다.
💡
다른 것을 다 설정하더라도, 파이프를 설정하지 않으면 무용지물이다!
import { ValidationPipe } from '@nestjs/common/pipes/validation.pipe'; import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.useGlobalPipes( new ValidationPipe({ // 유효성 검사용 파이프 추가 whitelist: true, // 데코레이터가 없는 프로퍼티는 거른다. forbidNonWhitelisted: true, // 데코레이터가 없는 프로퍼티는 에러로 처리한다. transform: true, // 기본적으로 url에 있는 것은 모두 string으로 처리되는데, 그게 아니라 알아서 적절한 타입으로 변환해달라는 의미 (string, number 등) }), ); await app.listen(3000); } bootstrap();
 

DTO에 유효성 검사 로직 추가

import { IsString, IsNumber } from 'class-validator'; export class CreateMovieDto { @IsString() // title이 string인지 유효성 체크 readonly title: string; @IsNumber() // year이 number인지 유효성 체크 readonly year: number; @IsString({ each: true }) // genres 배열에 있는 모든 요소가 string인지 유효성 체크 readonly genres: string[]; }
DTO에 유효성까지 지정
그 밖에도 @IsEmail(), @isEnum(<이넘종류>) 등 다양한 validation 메소드 제공함
 
notion image
우리가 정의한 DTO 타입대로 전송하지 않으니 400 에러를 띄우는 모습이다.
즉, 이제 input data에 대한 유효성 검사를 할 수 있게 되었다!
whiteList 정책에 위배되는 프로퍼티를 전송하였을 때는 해당 프로퍼티는 존재하면 안된다고 에러로 반환함.
 

DTO의 이점

💡
DTO를 타입으로 명시한다고 해서, 사용자가 DTO 대로만 보낼 수 있는 것은 아니다.
  1. DTO를 설정하면서 얻을 수 있는 이점은 타입을 지정함으로써 얻을 수 있는 이점과 같다.
  1. 파이프를 통해 유효성 검사 시 활용할 수 있다.
 

Graphql의 Field() 데코레이션 활용

export class LoginOutput extends MutationOutput { @Field((type) => String, { nullable: true }) token: string; }
이 필드는 String 타입이며, null이 될 수 있다 라는 것을 명시함.
graphql 라이브러리의 데코레이터다.