DTO 란?
DTO (Data Transfer Object) 란,
계층 간 데이터 전송을 위해 사용되는 객체이다.
DTO의 역할
- 요청에서 받아온 데이터를 타입에 맞게 바인딩하고 유효성 검사 수행
- Controller 계층과 Service 계층 사이에 데이터를 전달
- 응답 객체로 데이터를 클라이언트에 전달
NestJS에서의 DTO의 형태
export class CreateUserDto {
@IsNotEmpty()
name: string;
@IsNotEmpty()
password: string;
@IsNotEmpty()
email: string;
@IsOptional()
gender?: string;
}
- 클래스로 선언
- Typescript와 class-validator 사용
- 강력한 데이터 유효성 검사 기능
DTO 작성 및 적용
예시로 간단한 게시글 작성 기능에 적용해 보겠다.
먼저, class-validator와 class-transformer를 설치한다.
yarn add class-validator class-transformer
dto 파일을 작성한다.
# src/board/dtos/create-board.dto.ts
import { IsNotEmpty, MaxLength, MinLength } from 'class-validator';
export class CreateBoardDto {
@IsNotEmpty()
@MinLength(2)
@MaxLength(20)
title: string;
@IsNotEmpty()
content: string;
}
클라이언트에서 넘어오는 데이터에 dto를 이용하여 타입을 명시해 준다.
# src/board/board.controller.ts
...
@Post()
create(@Body() data: CreateBoardDto) {
return this.boardService.create(data);
}
하지만, 바로 validation이 적용되지 않는다.
이때, 파이프(Pipe)의 개념을 알아야 한다.
파이프는 클라이언트의 요청이 라우터로 도달하기 전에 실행되는 로직 중 하나이다.
파이프의 역할은 다음과 같다.
- 유효성 검사 - 요청을 처리하기 위해 입력된 데이터가 DTO에 명시된 형태와 일치하는지
- 데이터 변환 - 입력된 데이터를 다른 형태로 변환
NestJS에서는 여러 가지 내장 파이프들이 존재하고, 우리가 사용할 파이프는 ValidationPipe이다.
global로 적용할 수도 있고 여러 가지 적용방법이 있지만, 메서드에 적용하는 방식으로 진행해 보겠다.
@Post()
create(@Body(new ValidationPipe()) data: CreateBoardDto) {
return this.boardService.create(data);
}
위와 같이 작성하면 유효성 검사가 잘 작동한다.