DTO란? DTO의 정의 (with Martin fowler’s)

Jongho Jeon
Jongho’s Tech Blog
8 min readOct 10, 2022

DTO: Data Transfer Object는 개발자 커뮤니티나 개발자 논의에서 항상 나오는 용어이다. 개발자들끼리도 DTO에 대한 이해가 조금씩 다르다. 이 포스트에서는 몇몇 웹 문서를 인용하여 DTO의 정의를 정리한다.

DTO의 정의

유명 개발자들의 글에서도 DTO가 같은 의미로 사용된 것인지 아닌지 헷갈릴 때가 있다. 중요한 것은 자신만의 명확한 정의가 있고 이를 설명할 수 있어야한다는 것이다.

https://martinfowler.com/ 에 DTO의 정의에 대한 글이 있다. 이 글을 읽어보았다.

https://martinfowler.com/eaaCatalog/dataTransferObject.html

An object that carries data between processes in order to reduce the number of method calls.

번역: 프로세스 사이에서 메소드 호출 수를 줄이기 위해 데이터를 운반하는 오브젝트

프로세스라 함은 다른 물리 장비에 실행 중인 프로세스라고 생각해도 괜찮다. 위 문장에서, DTO가 프로세스 사이 통신을 위해 serialize하기 위한 용도가 아니라 메소드 호출 수를 줄이기 위한 용도라는 부분에서 의문이 들었다. (이를 읽으며 DTO에 대한 생각이 조금 바뀌었다.)

… Usually an assembler is used on the server side to transfer data between the DTO and any domain objects.

번역:보통 assembler는 서버 측에서 사용되며 DTO와 도메인 오브젝트 사이에서 데이터를 옮기기(transfer) 위하여 사용된다.

위 문장 및 다이어그램에서 DTO는 도메인 오브젝트로부터 생성 또는 도메인 오브젝트로 변환되는 오브젝트임을 알 수 있다.

실제 구현에서는 assembler같은 역할의 객체를 만들 수도 있고, 다른 방법도 있다. 본인은 DTO에 DTO 생성을 위한 static method를 만든다. (static factory method — design pattern)

Many people in the Sun community use the term “Value Object” for this pattern. I use it to mean something else. See the discussion on page 487.

번역: 많은 사람들이 DTO 패턴에 Value Object (VO)라는 용어를 사용하는데,나(마틴 파울러)는 다른 의미로 사용한다.

본인도 DTO와 VO를 다른 의미와 역할의 용어로 사용하는데, 기회가 되면 다른 포스트에서 다루겠다.

Object Serialization (객체 직렬화)

도메인 오브젝트가 어떻게 serialize될 것인지 결정하는 것은 DTO가 아닌 Serializer의 역할이라고 할 수 있다. Java/Spring에서 많이 사용되는 serializer 중 하나로 Jackson ObjectMapper가 있다. 도메인 객체에 @JsonProperty 또는 @JsonIgnore 와 같은 어노테이션을 사용하여 serialize되는 형태를 제어할 수 있다.

Reducing method calls (메소드 호출 횟수 감소)

When you’re working with a remote interface, such as Remote Facade (388), each call to it is expensive. As a result you need to reduce the number of calls, and that means that you need to transfer more data with each call.

번역: Remote Facade와 같은 원격 인터페이스와 통신할 때 호출 1회의 비용은 비쌈. 따라서 호출 수를 감소시켜야 하고 이는 각 호출에서 더 많은 데이터를 전송해야한다는 것을 의미함.

2번 리소스를 요청하는 방법
한 번에 두 리소스를 요청하는 방법

마틴 파울러의 글에서 말하는 것은 위와 같이 DTO를 활용하여 호출 수를 줄이는 것이다. (이것이 DTO의 용도라는 것이다)

DTO를 다른 의미로 사용하는 사람들도 있을 수 있는데, 그들이 틀린 것은 아니라고 생각한다.

DTO에 대한 다른 글들

아래 글은 User, Role이라는 예제로 DTO 사용방법을 소개하고 있으니 관심이 있다면 읽어보자. Martin fowler의 정의를 인용하고 있다.

https://www.baeldung.com/java-dto-pattern

아래 글에서는 Martin fowler의 DTO 정의와 Core J2EE Patterns: Best Practices and Design Strategies의 DTO 정의를 둘다 언급하고 있다. 후자는 VO와 동일한 개념으로 정의된다.

MS Docs에 DTO(데이터 전송 개체) 만들기 문서도 읽어보자. 본인은 실제로 이런 방식으로 구현해왔다.

그 외

DTO를 (도메인 오브젝트의) 레이어의 관심사 분리 용도로 사용할 수도 있다.

더 다양한 고려사항

실제로 개발을 하다보면 고려사항은 하나가 아니다.

  • Domain object에서 필드 이름이 CamelCase인데 snake_case로 serialize하고 싶을 수도 있다.
  • 일부 필드는 외부 API에서 숨기고 싶을 수도 있다.
  • 필드의 값이 null일 때 empty string(“”)으로 serialize하고 싶을 수도 있다.
  • 성능 상의 이유로 일부 API에서는 최소한의 필드들만 serialize하고 싶을 수도 있다.
  • Domain object가 JPA Entity이고 OneToMany 연관 엔티티 프로퍼티를 가진다면, N+1 problem 또는 persistence context의 영향을 받을지도 모른다.

Conclusion

중요한 것은 위와 같이 다양한 고려사항들을 충족하기 위하여 DTO를 적절히 활용하는 것이다. 함께 개발하는 팀원들과 용어에 대한 정의를 동기화하고 소통에 문제없도록 하는 것이 제일 중요하다. :)

여담: Martin fowler가 LocalDTO라는 용어도 만든 것 같은데, 아직 읽어보지는 못했다.

--

--