DTO와 Interface 분리, 진짜 효과가 있을까?

여리·2025년 6월 10일

해당 내용은 NestJs와 typescript 기반의 내용으로 작성되었습니다.

NestJS, TypeScript 기반 프로젝트에서 흔히 고민하게 되는 주제 중 하나가 바로 DTO와 Interface의 분리입니다.
저 역시 초기에는 DTO만 사용했고, 실제로도 큰 문제 없이 서비스를 운영해왔습니다.
그런데 최근 기술과제에서 다음과 같은 요구를 받았습니다:

"Interface를 정의해주세요. 클라이언트에서 같은 타입을 사용할 수 있다고 가정해요."

이 경험을 통해 저는 처음으로 "DTO와 Interface를 나눠야 할까?"라는 질문을 깊게 하게 되었고,
이번 글을 통해 그 고민의 여정과 정리한 인사이트를 나눠보려 합니다.


🧱 우선, 용어 정리부터

  • DTO (Data Transfer Object): 주로 입력/출력 데이터의 구조를 정의.
    class로 구현하며, 유효성 검증(class-validator) 등을 걸 수 있음.

  • Interface: 객체의 타입 정의를 위한 구조.
    런타임에 존재하지 않으며, 타입 시스템 상에서만 의미를 가짐. interface 또는 type으로 선언.


🚧 내가 겪었던 실제 구조

기존에는 이렇게 사용했습니다:

export class CreateUserDto {
  @IsString()
  name: string;

  @IsEmail()
  email: string;
}

이 DTO 하나로 controller, service, client 응답, swagger까지 모두 커버했죠.
간단한 CRUD에서는 매우 효율적입니다.

하지만 기술과제에서는 이런 요구사항이 붙었죠:

  • interface를 따로 정의
  • 클라이언트와 공통으로 사용할 수 있는 타입 제공

그래서 다음과 같이 코드를 나눠 사용했습니다:

// user.interface.ts
export interface User {
  name: string;
  email: string;
}

// create-user.dto.ts
export class CreateUserDto implements User {
  @IsString()
  name: string;

  @IsEmail()
  email: string;
}

🤔 분리해서 얻은 것 vs 불편한 점

✅ 분리의 장점

  1. 타입 공유: interface는 런타임 코드가 없어, 클라이언트와 API 문서에 공유하기 적합
  2. 유연한 확장성: DTO는 validation 로직 포함, Interface는 구조 정의에만 집중
  3. 테스트 코드 / 모킹 시 유리: 실제 DTO를 몰라도 Interface만으로 테스트 가능

❌ 분리의 단점

  1. 중복 선언: 같은 속성을 두 번 선언해야 함
  2. 유지보수 부담: 속성 변경 시 두 파일 모두 수정해야 함
  3. 실제 구현과 type이 불일치할 위험

🔍 다양한 케이스별 정리

상황Interface만DTO만둘 다 사용
클라이언트 타입 공유✅❌✅
NestJS 유효성 검증❌✅✅
내부 로직에서 단순 타입 체크✅✅✅
API 문서 자동화 (Swagger)❌✅✅
테스트/모킹 유연성✅❌✅

✅ 언제 interface와 DTO를 분리해야 할까?

  1. 클라이언트/서버 간 타입을 공유해야 한다면 → 분리
  2. DTO에 validation이 포함된다면 → class 기반 DTO 사용 + interface 분리 권장
  3. Swagger 문서 자동 생성 등 NestJS 기능을 활용한다면 → DTO는 필수

💡 실무 팁

  • DTO는 런타임 검증 + 문서 자동화에 필수
  • interface는 가볍게 타입 정의만 할 때 유리
  • implements Interface를 통해 중복을 줄이는 방향으로 관리 가능
  • type, Pick<T, K>, Omit<T, K> 등을 활용하면 중복 선언도 줄일 수 있음

✍️ 마무리하며

"인터페이스와 DTO를 분리한다고 진짜 효과가 있을까?"
그에 대한 제 결론은 이렇습니다:

단순한 CRUD에서는 굳이 분리할 필요는 없지만,
확장성, 타입 공유, 테스트 환경까지 고려한다면 분리해서 관리하는 것이 장기적으로 더 유리하다.

당장은 귀찮을 수 있어도, 프로젝트 규모가 커질수록 그 진가가 드러납니다.


혹시 여러분도 같은 고민을 해보셨나요?
다른 팀에서는 어떤 기준으로 interface와 DTO를 관리하고 있는지도 궁금합니다!

profile
beckend developer

0개의 댓글