목차
DTO란?
DTO(Data Transfer Object, 데이터 전송 객체)란 프로세스 간에 데이터를 전달하는 객체를 의미합니다. 말 그대로 데이터를 전송하기 위해 사용하는 객체라서 그 안에 비즈니스 로직 같은 복잡한 코드는 없고 순수하게 전달하고 싶은 데이터만 담겨있습니다. 아래의 그림을 통해 DTO는 주로 클라이언트와 서버가 데이터를 주고받을 때 사용하는 객체임을 알 수 있습니다.
참고
DTO란 무엇이고 왜 사용해야 할까?
밑의 예제 코드는 전부 NestJS + TypeOrm 환경에서 작성되었습니다. 트리스티가 Nest Js를 공부하며 남긴 기록입니다. 틀린 내용은 언제든지 말씀해주세요 ~! 📢 DTO란 무엇인가요? DTO(Data Transfer Object,
tristy.tistory.com
사용방법
yarn add class-validator
yarn add class-transformer
main.ts에 추가해준다.
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe());
await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
아래와 같이 객체안에 검증 annotation을 해준뒤 원하는 오류메세지를 설정해 줄 수 있다.
import { IsString } from 'class-validator';
export class CreatePostDto {
@IsString({
message: 'title은 string타입을 입력해 주어야 합니다!',
})
title: string;
@IsString({
message: 'content는 string타입을 입력해 주어야 합니다!',
})
content: string;
}
@Post()
@UseGuards(AccessTokenGuard)
postPosts(@User('id') userId: number, @Body() body: CreatePostDto) {
return this.postsService.createPost(userId, body);
}
우리는 entity와 겹치는 부분인 content와 title만 가져다 쓰고 싶으면 다음과 같이 하면 된다.
import { IsString } from 'class-validator';
import { BaseModel } from 'src/common/entity/base.entity';
import { UsersModel } from 'src/users/entities/users.entity';
import {
Column,
Entity,
ManyToOne,
} from 'typeorm';
@Entity()
export class PostsModel extends BaseModel {
//절대적으로 겹치지 않는 칼럼 생성
// 1) UsersModel과 연동한다. Foreign Key를 이용해서
// 2) null이 될 수 없다.
@ManyToOne(() => UsersModel, (user) => user.posts, {
nullable: false,
})
author: UsersModel;
@Column()
@IsString({
message: 'title은 string타입을 입력해 주어야 합니다!',
})
title: string;
@Column()
@IsString({
message: 'content는 string타입을 입력해 주어야 합니다!',
})
content: string;
@Column()
likeCount: number;
@Column()
commentCount: number;
}
그래서 다음과 같이 dto코드를 바꾸면 오류가 난다.
import { IsString } from 'class-validator';
import { PostsModel } from '../entities/posts.entity';
export class CreatePostDto extends Pick<PostsModel, 'title' | 'content'> {}
타입이 아닌 값으로 상속 받아야 하기 때문에 PickType으로 바꾸면 해결된다.
import { IsString } from 'class-validator';
import { PostsModel } from '../entities/posts.entity';
import { PickType } from '@nestjs/mapped-types';
//Pick, Omit, Partial ->type 반환
//PickType OmitType PartialType -> 값 반환
export class CreatePostDto extends PickType(PostsModel, ['content', 'title']) {}
그렇다면 updatePostDTO도 한번 만들어 보자
아래와 같이 PartialType을 쓰게 되면 옵셔널 체이닝을 사용할 수 있다.
물론 extends를 쓰지 않아도 된다. 하지만 상속성을 잘 표현하기 위해 다음과
같이 쓰는 것이 적절한 방향이라고 볼 수 있다.
import { IsOptional, IsString } from 'class-validator';
import { CreatePostDto } from './create-post.dto';
import { PartialType } from '@nestjs/mapped-types';
export class UpdatePostDTO extends PartialType(CreatePostDto) {
@IsString()
@IsOptional()
title?: string;
@IsString()
@IsOptional()
content?: string;
}
Validation Message 일반화
기능
/**
* ValidationArguments의 프로퍼티들
*
* 1) value -> 검증 되고 있는 값 (입력된 값)
* 2) constraints -> 파라미터에 입력된 제한 사항들
* args.constraints[0] -> 1
* args.constraints[1] -> 20
* 3) targetName -> 검증하고 있는 클래스의 이름
* 4) object -> 검증하고 있는 객체
* 5) property -> 검증 되고 있는 객체의 프로퍼티 이름
*/
사용예시
import { ValidationArguments } from 'class-validator';
export const lengthValidationMessage = (args: ValidationArguments) => {
if (args.constraints.length === 2) {
return `${args.property}은 최대 ${args.constraints[0]}~${args.constraints[1]}글자를 입력 해주세요!`;
} else {
return `${args.property}는 최소 ${args.constraints[0]} 글자를 입력 해주세요!`;
}
};
이런식으로 message를 각각마다 작성하지 않고 일반화하여 사용할 수 있다.
강의출처
[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core 강의 | 코드팩토리 -
코드팩토리 | 자바스크립트, 타입스크립트 다음은 백엔드 개발! NestJS를 이용한 REST API 백엔드 개발, Socket IO 개발 및 배포를 할 수 있게 됩니다., 백엔드가 처음이어도 누구나 OK! 트렌디한 NestJS로
www.inflearn.com
'코딩 정보 > NestJs' 카테고리의 다른 글
[NestJs] 커서 기반 페이지네이션을 구현해보자 (0) | 2025.01.29 |
---|---|
[NestJs] Class Transformer를 사용해 보자 (0) | 2025.01.28 |
[NestJs] 포스트맨 로그인 간편화 해보자 (0) | 2025.01.27 |
[NestJs] 토큰 가드를 구현해보자 (0) | 2025.01.24 |
[NestJs] 파이프에 대해 알아보자 (0) | 2025.01.21 |