DTO(Data Transfer Object)란 계층 간 데이터 전송을 위해 도메인 모델 대신 사용되는 객체이다.
DTO는 어떠한 비지니스 로직을 가져서는 안되며, 클라이언트 요청에 포함된 데이터를 담아 서버 측에 전달하고, 서버 측의 응답 데이터를 담아 클라이언트에 전송하는 계층 간 전달자 역할을 한다.
DTO는 반드시 사용해야 할까? 사실, DTO를 사용하는 것은 귀찮은 작업일 수 있다. 요청과 응답에 알맞은 DTO를 클래스를 새로 정의해야 하고, 모델의 필드가 변경되면 DTO 클래스도 수정해야 하는 번거로움이 있다. 소규모 프로젝트의 경우 DTO 사용이 불필요한 경우도 있다고 한다.
그럼에도 대부분의 상황에서는 DTO 사용을 권장한다. 그렇다면 DTO를 사용하는 이유에 대해서 알아보자.
먼저, Spring이나 NestJS처럼 Layered Architecture를 적용하는 프레임워크에서 DTO를 사용하지 않는 상황을 가정해보자. Controller가 클라이언트의 요청에 대한 응답으로 도메인 모델을 넘겨준다면 어떻게 될까?
도메인 모델의 메서드나 모든 속성이 그대로 외부에 노출된다. 따라서,
DTO를 사용하면 이러한 문제들을 해결할 수 있다. 도메인 모델을 캡슐화하여 보호하고, 모델과 뷰 간의 결합을 느슨하게 만든다. 또한, 클라이언트가 필요한 데이터만 선택적으로 전송할 수 있다.
그렇다면 엔티티(도메인 모델)와 DTO를 분리해서 사용해야 하는 이유는 뭘까? DTO를 사용해야 하는 이유에는 다음과 같은 것들이 있다.
관심사의 분리(separation of concerns)는 소프트웨어 분야의 오랜 원칙 중 하나로, 서로 다른 관심사들을 분리하여 변경 가능성을 최소화하고, 유연하며 확장 가능한 구조로 만드는 것이다.
DTO의 핵심 관심사는 데이터의 전달이다. DTO는 데이터를 담고 다른 계층으로 데이터를 넘겨주기 위한 객체이다. 그러므로 어떠한 기능 및 동작도 없어야 한다.
반면에, 엔티티는 핵심 비지니스 로직을 담는 비지니스 도메인 영역의 일부이다. 그러므로 엔티티 또는 도메인 객체에는 비지니스 로직이 추가될 수 있다. 이들은 다른 계층 사이에서 전달을 위해 사용되는
객체가 아니다.
좋은 객체 지향 설계를 위해서는 하나의 객체에는 하나의 책임만이 존재해야 하며, 엔티티와 DTO는 서로 다른 관심사를 가지고 있기 때문에 분리하는 것이 합리적이다.
Patterns of Enterprise Application Architecture(P of EAA)의 저자 마틴 파울러는 DTO의 주요 목적에 대해 아래와 같이 언급했다.
The main reason for using a Data Transfer Object is to batch up what would be multiple remote calls into a single call
데이터 전송 개체를 사용하는 주된 이유는 여러 원격 호출을 단일 호출로 일괄 처리하는 것이다.
우리가 원격 인터페이스로 작업을 할 때, 호출에 따른 비용은 매우 비싸다. 때문에 우리는 요청의 횟수를 줄여야 하고, 이를 위해 한번의 요청에 더 많은 데이터를 전송해야 한다. 우리는 이를 수행하기 위해 많은 매개변수를 사용할 수 있다. 그러나 이것은 프로그래밍하기 어려운 방법일 뿐더러, JAVA에서는 반환값으로 여러 개의 값을 받을 수 없으므로 더욱 불가능한 일이라 할 수 있다. 그렇기 때문에, 우리는 요청에 대한 모든 데이터를 보관할 수 있는 데이터 전송 객체, DTO를 만들어 사용한다.
외부와 통신하는 프로그램에 있어 호출은 큰 비용이며, 이를 줄여 효율적으로 값을 전달할 필요가 있다. 이를 위해 데이터를 모아 한 번에 전달하는 방법이 고안되었고, 이에 사용되는 객체를 DTO라고 한다.
(참고한 블로그에서 이해를 돕기 위한 질문과 답변이 있었다.) https://okky.kr/articles/1293573
이 밖에 이점들로는 다음과 같은 것들이 있다.
지금까지 DTO가 필요한 이유에 대해 알아보았다. 그렇다면 어느 계층에서 DTO를 주고 받아야 할까? 사실, 이 질문에 대해서는 절대적인 정답은 없는 것 같다. 여러 글을 참고해 보았는데 의견이 분분하다.
Reference
https://tecoble.techcourse.co.kr/post/2021-04-25-dto-layer-scope/
https://e-una.tistory.com/72
https://mangkyu.tistory.com/192
https://martinfowler.com/eaaCatalog/dataTransferObject.html
https://okky.kr/questions/1293573