DTO란?예시Validation 추가필요 라이브러리 설치main.ts에 유효성 검사를 위한 파이프 추가DTO에 유효성 검사 로직 추가DTO의 이점Graphql의 Field() 데코레이션 활용
DTO란?
Data Transfer Object
로, 영어 그대로 데이터를 전송하는 오브젝트를 뜻함.사용자가 보냈으면 하는 데이터 형식을 DTO로 정의하고, API 인풋의 타입으로 활용한다.
예시
export class CreateMovieDto { readonly title: string; readonly year: number; readonly genres: string[]; }
... @Post() create(@Body() movieData: CreateMovieDto) { // movieData의 타입은 CreateMovieDto 이라는 뜻 return this.moviesService.create(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[]; }
그 밖에도
@IsEmail()
, @isEnum(<이넘종류>)
등 다양한 validation 메소드 제공함
우리가 정의한 DTO 타입대로 전송하지 않으니 400 에러를 띄우는 모습이다.
즉, 이제 input data에 대한 유효성 검사를 할 수 있게 되었다!
whiteList 정책에 위배되는 프로퍼티를 전송하였을 때는 해당 프로퍼티는 존재하면 안된다고 에러로 반환함.
DTO의 이점
DTO를 타입으로 명시한다고 해서, 사용자가 DTO 대로만 보낼 수 있는 것은 아니다.
- DTO를 설정하면서 얻을 수 있는 이점은 타입을 지정함으로써 얻을 수 있는 이점과 같다.
- 파이프를 통해 유효성 검사 시 활용할 수 있다.
Graphql의 Field() 데코레이션 활용
export class LoginOutput extends MutationOutput { @Field((type) => String, { nullable: true }) token: string; }
이 필드는 String 타입이며, null이 될 수 있다 라는 것을 명시함.
graphql 라이브러리의 데코레이터다.