개요

클라이언트에서 서버로 들어오는 요청 데이터를 DTO로 다루면 변환과 검증의 경계를 명확히 유지 가능함 class-transformer는 입력을 클래스 인스턴스로 변환하는 역할, class-validator는 변환된 인스턴스의 유효성 검증 역할 두 라이브러리를 함께 쓰면 DTO 레이어에서 데이터 정합성을 선제적으로 보장 가능함

핵심 개념

  • DTO 데이터 전송 객체, 외부 입력을 내부 도메인으로 들이기 전 구조와 제약을 고정하는 경계
  • class-transformer plain object ↔ 클래스 인스턴스 변환, 노출/제외 필드 제어
  • class-validator 데코레이터 기반 유효성 규칙 선언, 실행 시 검증 에러 수집

설치

npm install class-transformer class-validator

사용 흐름과 최소 예시

  • 입력 JSON 수신 → DTO 클래스로 변환 → DTO 인스턴스 검증 → 실패 시 에러 응답, 성공 시 비즈니스 로직으로 전달
import { Expose, Exclude, plainToInstance } from 'class-transformer'
import { IsInt, IsString, validate } from 'class-validator'

class UserDTO {
  @IsString()
  @Expose()
  name: string

  @IsInt()
  @Expose()
  age: number

  @Exclude()
  password?: string
}

const dto = plainToInstance(UserDTO, payload)
const errors = await validate(dto)
if (errors.length) {
  // 검증 실패 처리
}

포인트

  • plainToInstance로 클래스 인스턴스 생성
  • validate로 데코레이터 규칙에 따라 유효성 확인
  • 실패 시 errors에 필드, 제약, 메시지 포함

@Expose와 @Exclude로 변환 제어

  • @Expose 변환 시 포함 대상 명시, DTO가 의도한 필드만 노출
  • @Exclude 변환 시 제외 대상 명시, 민감정보 누락 보장
  • 보수적으로 @Exclude 기본 적용 후 필요한 필드만 @Expose로 허용하는 화이트리스트 전략 권장

실패 사례와 에러 포맷

  • name에 숫자, age에 문자열 입력 같은 타입 불일치 발생 시 검증 실패
  • 대표 에러 구조 예시
    • property 검증 대상 필드명
    • value 입력값
    • constraints 위반된 규칙과 메시지 맵
  • 이 정보로 400 응답 본문을 표준화하거나 로깅에 활용 가능

주의사항과 베스트프랙티스

  • 타입 변환 기대치 명시 필요
    • class-validator는 타입 강제 변환을 수행하지 않음
    • 문자열 “123"을 숫자로 쓰고 싶다면 class-transformer 설정으로 명시적 변환 추가 또는 DTO 필드에 적절한 변환 로직 구성
  • 입력 신뢰 금지 원칙
    • DTO는 외부 경계, 모든 필드에 최소한의 제약 부여 권장
    • 필요 시 커스텀 제약으로 도메인 규칙 캡슐화
  • 에러 메시지 관리
    • 내부용 상세 메시지와 외부 노출 메시지 분리
    • 다국어나 코드 기반 메시지 테이블로 매핑하는 어댑터 계층 둠
  • 직렬화 경계 유지
    • 컨트롤러 응답 직전에도 class-transformer로 직렬화 스텝 명시, @Exclude 누락으로 민감정보 노출되는 사고 방지
  • 테스트 전략
    • DTO 단위테스트에 정상/에지/악성 페이로드 케이스 고정
    • 스냅샷보다 constraints 키 기반 검증 권장

간단 패턴 정리

  • 입력 수신 → plainToInstance(UserDTO, input)
  • validate(dto) → 실패 시 에러 매핑 후 400 반환
  • 성공 시 비즈니스 로직 실행, 응답 직전 직렬화 단계에서 @Expose/@Exclude 적용

마무리

class-transformer와 class-validator를 DTO 경계에 결합하면 변환과 검증을 선언적으로 관리 가능함 입력 정합성을 초기에 보장하고, 민감정보 노출을 통제하며, 도메인으로 들어오는 데이터의 품질을 균일하게 유지할 수 있음 적절한 변환 정책, 에러 표준화, 테스트 고정으로 운영 안정성 향상 기대

참고자료