우리 팀에서는 다음과 같이 DTO의 이름을 네이밍하고 있다.
- save / find / update / delete
- 요청 DTO : (자원) - (조작 행위)
- 자원 - 저장 : ResourceSaveRequest
- 자원 - 수정 : ResourveUpdateRequest
- 응답 DTO : (자원) - (자원 속성 | 관련 조건) - (단건 | 여러 건)
- 자원 - 조건 없음 - 단건 : ResourceFindOneResponse
- 자원 - 검색 - 여러 건 : ResourceSearchAllReponse
- 자원 - 다른 자원 근처 - 여러 건 : ResourceNearbyAllResponse
하지만 클래스 이름이 길어지고 조건도 여럿 생기면 너무 길어진다.
MessageTemplateSaveUpdateRequest
MessageHistoryByMessageTemplateAllResponse
package by feature 방식이라면, 다음과 같이 사용할 수 있겠다. dto 내에 message 패키지가 존재한다고 하자.
TemplateSaveUpdateRequest
HistoryByTemplateAllResponse
즉 Message를 생략할 수 있다. 그러면 문제. 만약에 Template
패키지가 존재한다면?
템플릿이라는 별도 도메인의 dto를 저장하고 업데이트하는 TemplateSaveUpdateRequest
가 존재한다면?
템플릿 DTO는 템플릿 컨트롤러 / 서비스에서 사용된다. 메세지의 템플릿 DTO는 메세지 컨트롤러 / 서비스에서 사용된다. 따라서 둘 사이의 모호성이 생길 일은 없다.
여러 도메인에서 공유되는 임베디드 타입을 사용하는 경우 DTO 변환에서 문제가 생길 수도 있다. 예약과 대기 도메인에서 '담당자' 라는 임베디드 타입이 존재한다고 치자. 이때, 담당자 임베디드 타입은 중복을 없애기 위해 중앙의 model
내지는 common
패키지로 분리될 수 있다. 즉 예약이나 대기 도메인 둘 중 어느 곳에도 소속되지 않는다.
그런데 예약 도메인에서 예약 정보를 조회하는 API를 만들고, 대기 도메인에서는 대기 정보를 조회하는 API를 만든다고 하자. 예약 정보 API의 manager 필드에 담당자 정보가 들어가고, 대기 정보 API의 manager 필드에 담당자 정보가 들어간다. 이때, 두 manager 필드에 들어가는 담당자 DTO가 서로 다르다면 어떨까? 가령 예약 정보 API의 경우 1) 예약자 id 2) 예약자 이름이 3) 예약자 관련 특이사항을 ManagerDTO
로 가지고, 대기 정보 API의 경우 1) 대기자 id 2) 대기자 이름만 ManagerDTO
로 가지고 있다면, 같은 ManagerDTO
를 사용할 수 없다.
이 경우 ManagerByReservationDTO
, ManagerByWaitingDTO
와 같이 DTO를 구분해야 하는 방식으로 처리한다. 두 유형의 ManagerDTO
를 예약 패키지와 대기 패키지에 만들 수도 있지만, 이렇게 하면 Manager
모델이 분산되어 있어 관리가 어려워진다.
결론이 뭐냐? 위에서 했던 것처럼 여러 도메인에서 공유되는 임베디드 타입의 경우, DTO로 변환할 때 패키지 이름을 생략하면 안된다. 애초에 패키지 이름을 생략할 수 있는 이유가 하나의 패키지 내에서만 사용할 수 있다는 전제에서 근거하기 떄문이다.