[Spring] DTO를 나누는 기준은 어떻게 고려해야할까?
DTO를 나누는 기준에 대해 알아보자.
- API 응답을 위한 DTO는 왜 나눠야 하는가?
- 1. 하나의 도메인, 여러 개의 응답 목적
- 2. “필드 수”가 아니라 “의도”로 판단해야 한다
- 3. DTO 설계는 “View 기반”이어야 한다
- 4. DTO 분리의 장점 – 실무 중심으로 요약
- 결론
✅ API 응답을 위한 DTO는 왜 나눠야 하는가?
서비스 개발을 하다 보면 DTO(Data Transfer Object)를 여러 개 만들게 된다. 처음에는 같은 도메인 모델에서 파생되는 응답 DTO라면 하나로 통일할 수 있지 않을까? 하는 생각이 들기도 한다. 하지만 실제로 API를 설계하고 클라이언트와 연동하는 과정을 겪어보면, DTO를 목적에 따라 나눠야 하는 이유가 분명히 보이기 시작한다.
1️⃣ 하나의 도메인, 여러 개의 응답 목적
실제로 PeerReview
라는 동일한 도메인을 기반으로 하더라도, API마다 응답 목적이 전혀 다르다.
클래스 | 목적 | 사용되는 API |
---|---|---|
PeerReviewDetailResponse | 단일 리뷰의 상세 정보 제공 | 리뷰 생성 응답, 리뷰 상세 조회 |
UserReviewSummaryResponse | 특정 사용자의 리뷰 통계 요약 | 사용자 리뷰 평균 조회 |
ProjectReviewStatusResponse | 프로젝트 리뷰 진행 상태 확인 | 프로젝트별 리뷰 완료 여부 확인 |
이처럼 동일한 도메인 모델이더라도 응답의 대상, 범위, 표현 방식이 다르면 DTO는 분리되어야 한다. 하나의 PeerReviewResponse
에 모든 필드를 때려넣고 공통으로 쓰다 보면,
- 어떤 API는 불필요한 데이터가 너무 많이 오가고,
- 어떤 API는 필요한 정보가 빠져 있어 클라이언트가 혼란을 겪는다.
❗️ “DTO 하나로 합쳐도 되지 않나요?” → 되긴 하지만, API의 명확한 역할과 응답 일관성을 해친다.
2️⃣ “필드 수”가 아니라 “의도”로 판단해야 한다
DTO를 나눌 때 흔히 하는 실수 중 하나가
“필드가 너무 적은데 굳이 따로 DTO로 만들어야 해?” 라는 의문이다.
내가 프로젝트를 하며 이런 고민을 계속 하고, 실제로 다른 사람들은 어떤 기준을 가지는지 찾아보다 이 글을 작성하게 되었다.
하지만 DTO는 포함된 데이터의 양이 아니라, 응답의 의도에 따라 나뉘어야 한다.
예시 비교
클래스 | 주요 필드 | 설명 |
---|---|---|
UserReviewSummaryResponse | 평균 점수, 리뷰 개수 | 사용자 요약 통계 |
PeerReviewDetailResponse | 리뷰 항목별 점수, 작성자 정보, 날짜 | 상세 정보 조회용 |
이 두 DTO는 필드 수만 보면 합칠 수 있을 것 같지만,
하나는 요약 정보 (Summary), 하나는 상세 정보 (Detail) 제공이라는 근본적인 목적이 다르다.
또한, Summary는 추후 차트
, 히스토그램
, 트렌드
같은 집계 데이터를 추가하기에 더 적합한 형태이고, Detail은 사용자 경험 개선을 위한 리치한 UI 렌더링에 최적화된 형태로 확장될 수 있다.
3️⃣ DTO 설계는 “View 기반”이어야 한다
DTO는 도메인을 있는 그대로 노출하는 것이 아니라, API View Layer의 역할과 책임에 맞게 정보를 재가공해 전달하는 것이 목적이다.
즉, “어떤 정보를 어떻게 보여줄지”에 따라 설계되어야 한다.
잘못된 설계 예
- 불필요하게 내부 ID, 시스템 시간, 관리자용 정보 등을 포함한 DTO
- 클라이언트에 노출되면 혼란을 주거나, 보안상 문제될 수 있는 필드 포함
좋은 설계 예
- 사용자에게 필요한 정보만 간결하게 포함
- 실제 프론트 UI와 일치하는 정보 구조
- 데이터의 “의미”와 “구성 방식”이 API 목적과 맞아떨어짐
🧠 DTO는 단순히 데이터를 전달하는 구조체가 아니라, **“API 응답 설계 그 자체”**라는 것을 항상 기억해야 한다.
4️⃣ DTO 분리의 장점 – 실무 중심으로 요약
이유 | 설명 |
---|---|
명확한 책임 분리 | 각 API의 목적에 따라 DTO도 명확히 구분되어 유지보수가 쉬움 |
클라이언트 연동 안정성 | 응답 구조가 고정되기 때문에 프론트엔드와의 계약(Contract)이 안정됨 |
확장성 | 새로운 요구사항이 생겼을 때 불필요한 필드 추가 없이 필요한 DTO만 수정하면 됨 |
성능 최적화 | 불필요한 필드 제거로 응답 크기 감소 → 네트워크 비용 감소 |
테스트 단순화 | DTO 단위 테스트, API 응답 테스트가 더 명확하고 간결해짐 |
✅ 결론: API 목적 = DTO 목적
- 하나의 API가 명확한 역할을 가지듯,
- 그 API가 사용하는 DTO도 명확한 책임을 가져야 한다.
DTO는 설계의 산물이면서, 동시에 클라이언트와의 약속이다. 따라서 필드 개수가 적다고 DTO를 합치는 건 설계적 실수일 수 있으며, 응답 데이터는 목적, 의미, 유지보수, 확장성 관점에서 설계되어야 한다.
✍️ 마무리 한 줄 요약
DTO는 “얼마나 많은 데이터를 담는가”보다 “어떤 목적의 데이터를 담는가”가 더 중요하다.