-
NestJS 마스터 시리즈 6화. DTO와 Validation – 데이터 무결성과 API 품질의 시작기술과 산업/언어 및 프레임워크 2025. 4. 30. 12:43728x90
"API는 설계의 언어다. DTO는 그 언어의 문법이다"
NestJS에서 DTO와 유효성 검사를 어떻게 설계하고 적용할지, class-validator, Pipes, Transform 전략 등 실전 API 개발에서 꼭 필요한 개념을 설명합니다.
DTO란 무엇인가 – 단순한 포맷이 아니다
DTO(Data Transfer Object)는 클라이언트로부터 받거나 클라이언트로 전달할 데이터 구조의 명세서다.
NestJS는 TypeScript의 클래스 기반 구조를 활용해 DTO를 정의하며, 이를 통해 다음을 보장할 수 있다:- 입력값의 명확한 스펙 정의
- 자동 유효성 검사 및 에러 응답
- Swagger 등 문서화 도구와의 자연스러운 연계
"DTO는 단순히 타입을 정하는 것이 아니라, API의 규칙과 문화를 정하는 것이다."
실전 예제 – 사용자 생성 DTO
import { IsString, IsEmail, Length } from 'class-validator'; export class CreateUserDto { @IsEmail() email: string; @IsString() @Length(4, 20) password: string; @IsString() name: string; }
- class-validator의 데코레이터를 통해 유효성 검사를 선언
- 클래스 자체가 타입 정의와 validation 룰을 동시에 수행
Validation Pipe로 검사를 자동화하기
NestJS는 ValidationPipe를 통해 DTO를 기반으로 유효성 검사를 자동으로 수행할 수 있다.
import { ValidationPipe } from '@nestjs/common'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.useGlobalPipes(new ValidationPipe({ whitelist: true, forbidNonWhitelisted: true })); await app.listen(3000); }
옵션 설명:
- whitelist: true – DTO에 정의되지 않은 속성 제거
- forbidNonWhitelisted: true – 허용되지 않은 속성이 들어오면 요청 거절
- transform: true – DTO의 타입을 자동으로 변환
컨트롤러에 적용하기
@Post() create(@Body() createUserDto: CreateUserDto) { return this.usersService.create(createUserDto); }
- Nest는 @Body()에 지정된 클래스를 기준으로 유효성 검사를 수행하고, 실패 시 400 에러를 반환한다.
고급 전략 – Custom Validator 만들기
복잡한 검증 조건이 필요한 경우 커스텀 데코레이터를 만들 수 있다.
import { registerDecorator, ValidationOptions, ValidatorConstraint, ValidatorConstraintInterface } from 'class-validator'; @ValidatorConstraint({ async: true }) export class IsEmailUniqueConstraint implements ValidatorConstraintInterface { async validate(email: string) { // 이메일 중복 체크 로직 예시 return !(await UserRepository.existsByEmail(email)); } } export function IsEmailUnique(validationOptions?: ValidationOptions) { return function (object: Object, propertyName: string) { registerDecorator({ target: object.constructor, propertyName, options: validationOptions, constraints: [], validator: IsEmailUniqueConstraint, }); }; }
데이터 변환과 자동 타입 캐스팅 – Transform 활용
NestJS는 class-transformer와 함께 @Type()을 활용해 JSON 데이터를 객체로 자동 변환할 수 있다.
import { Type } from 'class-transformer'; import { IsDate } from 'class-validator'; export class BookingDto { @IsDate() @Type(() => Date) bookingDate: Date; }
- 클라이언트가 문자열로 보낸 날짜도 Date 객체로 자동 변환 가능
유효성 검사 실패 시 반환 구조
NestJS는 유효성 검사 실패 시 기본적으로 다음과 같은 구조로 응답한다:
{ "statusCode": 400, "message": [ "email must be an email", "password must be longer than or equal to 4 characters" ], "error": "Bad Request" }
이 구조는 글로벌 예외 필터(ExceptionFilter)를 통해 커스터마이징할 수 있다.
마무리 인사이트
DTO와 Validation은 단순한 데이터 검증을 넘어 API의 신뢰성과 품질을 결정짓는 핵심 요소다.
NestJS는 TypeScript의 타입 시스템과 데코레이터 기반 유효성 검사를 통해 이를 구조화된 방식으로 제공한다.- DTO는 명세서이며, 개발팀 간 계약이다.
- Validation은 방어적 설계이며, 실서비스의 무결성을 지키는 방패다.
제대로 설계된 API는 문서보다 DTO가 말해준다.
다음 회차 예고
7화. ConfigModule과 환경 설정 – .env 관리와 설정 계층 구조의 원칙
환경별 설정 분리 전략과 ConfigModule 확장 방식까지 다룬다.728x90'기술과 산업 > 언어 및 프레임워크' 카테고리의 다른 글
Spring Boot 시리즈 22편 – API 버전 관리 전략: URL, Header, Accept 기반 버전 설계 Best Practice (0) 2025.05.01 FastAPI 시리즈 1화 - FastAPI란 무엇인가? 탄생 배경과 주요 특징 분석 (1) 2025.04.30 Spring Boot 시리즈 21편 – 비동기 처리와 병렬 프로그래밍: @Async, CompletableFuture, Reactor 실전 사용법 (0) 2025.04.30 Spring Boot 시리즈 20편 – 메시지 큐 기반 비동기 아키텍처: Kafka, RabbitMQ로 확장성 강화 (0) 2025.04.29 Python 마스터 시리즈 3화 – 변수와 자료형 제대로 이해하기 (1) 2025.04.29