이전부터 Domain객체를 어디서 DTO로 변화 해야 하는지에 대한 고민이 있었다.
최근에 DTO의 사용 범위에 대하여 라는 테코블 글을 보게 되었다. DTO와 Domain객체에 대한 설명을 하고 이 글에 대한 언급을 하고 내 생각을 언급해보겠다.
MVC패턴은 어플리케이션을 Model/View/Controller 3가지로 분리하는 패턴이다. Model에서 비즈니스 로직을 처리하고 View에서는 화면을 뿌려준다. Controller는 Model과 View사이에서 연결을 담당한다.
레이어드 아키텍처에서 우리는 Controller,Service,Repository라는 3개의 계층을 활용하여 스프링 MVC를 구현한다. 이때 계층간의 데이터전송을 DTO(Data Transfer Object)로 한다.DTO는 계층간 데이터 교환을 위해 사용하는 객체이다.
DB에 데이터를 넣거나 가져올때 사용하는 객체이다.
DB에 Domain객체의 형태로 삽입되고 가져오기 때문에 굳이 Dto로 변환해야 하나?라는 의문이 있을 수 있다. Domain을 직접 응답하면 2가지의 문제점이 있다.
1. Domain의 구조가 클라이언트에게 노출된다.
2. 실제 프로젝트를 구현하면 API는 필요한 데이터만을 요청하는데 불필요한 데이터까지 넘어온다.
위와 같은 이유로 Domain을 직접 반환하지는 않고 Dto로 필요한 데이터만 담아서 반환해준다.
그렇다면 Controller,Service,Repository 3위치중 한곳에서 Domain을 Dto로 변환해야 한다는 이야기 이다. 어디서 반환하는게 좋을까? 정답이 없는 문제이고 내 생각을 먼저 말해보겠다.
Repository는 DB에 직접 접근하여 데이터를 관리하는 레이어이다. Entity를 관리하는 것이 Repository의 역할이기 때문에 적합하지 않다고 생각했다.
Controller에는 Dto가 무조건 있다. 하지만 Entity도 있어야하나?라는 생각이 있다.
Entity를 Controller까지 반환해서 Controller에서 사용하지도 않는 객체를 굳이 Controller에게 Domain객체의 존재를 알려야 할까라는 생각이 있다. Domain이 Controller까지 노출된다면 Domain의 변경위험이 Controller에도 존재하는게 마음에 들지 않았다.
난 프로젝트를 진행하고 API를 개발할 때 Dto객체의 변환을 Service레이어에서 진행한다.
즉 Domain객체를 Service까지 노출시킨다. Service레이어는 비즈니스 로직을 처리하는 곳이고 Dto변환도 비즈니스 로직의 일부라 생각하기 때문이다. 또한 Domain객체의 노출을 최소화 하기 때문에 뭔가 문제가 있다면 Service 레이어에서 찾으면 된다.
JPA강의를 듣다보면 김영한님은 Domain을 Controller까지 보내시는 것 같았다. 대부분 Controller에서 Dto로 변환하여 응답을 해주시는 걸 보고 나와는 생각이 다르다는 것을 느꼈다.
하지만 Domain을 직접 응답하시는 것은 좋지 않다고 말씀해주셨다.
테코블을 작성하신 분의 경우는 나와 생각이 비슷했다. 하지만 리뷰어분은 Controller에서 Dto를 반환하신다고 하셨다.

Service레이어에 Dto가 안들어 온다면 여러 종류의 컨트롤러에서 해당 서비스를 사용할 수 있는 장점이 있고 Dto가 Service계층까지 들어올 수 있다면 도메인으로 변환을 초기에 하지 않는다면 Repository까지도 들어올 수 있다는 단점이 있다. 라는 생각으로 컨트롤러에서 Dto로 변환한다고 하셨다.
무조건 Service에서만 Dto변환을 해야한다고는 생각하지 않는다. 하지만 왠만하면 Service에서 하는게 좋은 것 같긴하다. Controller에서 반환하면 Service부터는 깔끔하게 Domain객체만 있을 수 있고 특정 Dto에 의존하지 않는다는 장점도 생길 것 같다. 이전까지는 Service에서 바꿔야지라는 생각을 가지고 있었지만 이 글을 쓰고나니 또 헷갈린다ㅋ