DTO
DTO(Data Transfer Object)란 계층간 데이터 교환을 위해 사용하는 객체다.
MVC 패턴에서 컨트롤러가 뷰와 모델의 데이터를 주고 받을 때 보통 DTO를 사용한다.
도메인 객체(모델)을 뷰에 직접 전달할 수도 있지만,
뷰에 불필요한 민감한 도메인의 정보가 노출될 수도 있고, 도메인이 뷰에 의존하게 되는 경우도 있다.
DTO의 범위
모델과 뷰 사이에 DTO를 사용한다는 것은 알겠는데,
일반적으로 사용하는 레이어드 아키텍처 (Controller - Service - Repository)에서 DTO는 어떻게 다뤄야 할까?
조금 더 간단하게 말하자면,
결국 뷰와 같은 화면과, 비즈니스 로직의 데이터 교환은 DTO를 통해 이루어지는데,
도메인 → DTO, DTO → 도메인을 변환하는 작업은 어떤 계층에서 수행하는 것이 좋을까?
Repository
레포지토리는 본래 엔티티(도메인)의 영속성을 관장하는 역할을 한다.
이로 인해, 엔티티를 DTO로 변환하는 작업을 레포지토리 단에서 책임지게 하는 것을 지양하자는 의견이 다수 존재했다.
그럼 레포지토리는 자신의 역할에 충실하라고 하고 넘어가자.
Service
"서비스 레이어란 비즈니스 로직을 수행하고 도메인을 캡슐화하는 역할이다." ('리팩토링' 저자 마틴 파울러)
위 말을 정리하자면 서비스 레이어는 도메인을 보호한다.
비즈니스 로직과 도메인 보호를 책임지는 서비스와 다르게,
컨트롤러는 표현 계층(화면)에 대한 요청과 응답을 담당한다.
만약 도메인이 컨트롤러로 넘어간다면 도메인의 변경은 컨트롤러의 변경을 촉발하고 유지보수의 문제로 이어질 수 있다.
이러한 관점에서 컨트롤러 - 서비스 레이어간 데이터 전달을 DTO로 엄격하게 고수한다면,
DTO 변환 로직은 서비스 레이어에서 정의되어야 한다는 의견이 존재한다.
Controller
만약 컨트롤러가 서비스로부터 도메인을 받아서 DTO를 처리한다면,
1. 뷰에 반환할 필요가 없는 데이터까지 도메인 객체에 포함되어 컨트롤러에 넘어온다.
2. 컨트롤러가 여러 도메인 객체들의 정보를 조합해서 DTO를 생성하는 경우, 결국 비즈니스 로직이 컨트롤러에 포함될 수 있다.
또한, 컨트롤러가 DTO를 완벽하게 도메인 객체로 구성한 뒤 서비스에 넘겨준다면,
1. 복잡도에 따라 컨트롤러가 여러 서비스에 의존하게 된다.
→ 위 의견을 종합하면 DTO를 서비스에 넘겨주고 서비스에서 비즈니스 로직을 통해 도메인을 다룬 후, 다시 DTO 형태로 컨트롤러에 반환 하는 것이 더 나은 방법이라 생각된다.
참고자료
https://xlffm3.github.io/spring%20&%20spring%20boot/DTOLayer/
'java > spring' 카테고리의 다른 글
[Spring] @SpringBootTest vs @DataJpaTest (0) | 2023.07.15 |
---|---|
[SpringMVC] 타임리프 - 기본기능 (0) | 2023.07.08 |
[Spring] Service - 인터페이스 도입과 버저닝 (0) | 2023.06.26 |
[Spring] 의존성 역정 원리(DIP) 관련 용어 (0) | 2023.06.23 |
[Spring] @TransactionalEventListener에서 예외가 발생하지 않는 이슈 (2) | 2023.06.23 |