sprots echo 프로젝트 진행 중 dto와 entity 변환 메서드를 어디에 둘 것인가.. 를 두고 한바탕 토론이 있었다. 변환 메서드에는 requestDto를 entity로 변환하는 메서드, entity를 responseDto로 변환하는 메서드 두 가지가 있다.
1. dto에 두자!
변환 메서드는 dto에 두는 것이 일반적이다. dto 내부에 변환 메서드를 두면 dto와 entity가 각자의 책임을 갖기 때문에 클래스가 간결해질 수 있다. 다만 변환이 필요한 모든 레이어에서 중복될 수 있다.
2. entity에 두자!
엔티티 클래스가 변환 로직을 갖게 되면 변환이 적용되는 모든 레이어에서 일관성을 유지할 수 있다. 다만 해당 엔티티는 비지니스 로직 외에 변환 로직까지 책임져야 하므로 책임 원칙에 위배될 수 있다.
이에 대해 조언을 구하니 어디에 두든 결과적으로 같은 기능을 하기 때문에 그 자체가 크게 상관있지는 않다. 프로젝트의 성격에 맞게 구현하면 된다고 하신 분도 있고 엔티티에 변환 메서드를 두는 것은 좋지 않으니 dto에 둘 것을 추천하신 분도 있었다.
결론은 아이러니하게도 둘 다 아닌 Mapper를 사용해보자! 로 내렸다. 변환 방법에는 메서드를 직접 작성하는 것 뿐만 아니라 Mapper를 사용하는 방법도 있다는 것을 알게 되었는데 이는 코드를 간결하게 하고 효율적인 변환을 구현할 수 있다고 한다. 아직 공부하는 단계이므로 이를 적용해보면 좋을 것 같아서 Mapper를 사용하기로 하였다. (이에 대한 글은 따로 작성하기로 하자)
그렇다면 두번째 안건.. service에서 dto를 반환할 것인가 vs controller에서 dto를 반환할 것인가. 이는 서비스 로직에서 도메인을 반환할 것인지, dto를 반환할 것인지 ResponseEntity를 반환할 것인지에 대해 의견을 나누면서 확장된 안건이다.
우선 ResponseEntity를 서비스 로직까지 끌고 오는 것은 책임 분리 원칙에 맞지 않을 듯하니 컨트롤러에서 반환하는 것으로 빠르게 배제시켰다. 그렇다면 이제 서비스에서 도메인을 반환하고 컨트롤러에서 dto로 변환할 것인지, 아니면 서비스에서 dto 변환까지 하고 dto를 반환할 것인지..에 대한 고민을 해야한다.
1. Service에서 dto 변환
서비스 레이어에서 변환이 이루어지면 비지니스 로직과 서비스 로직의 분리가 강화되고, dto를 여러 컨트롤러에서 재사용할 수 있다는 장점이 있고, 컨트롤러에서 dto에 대한 추가 작업이 이루어질 수 있다는 단점이 존재한다.
2. Controller에서 dto 변환
컨트롤러가 직접 변환을 하게 되면 컨트롤러는 클라이언트에게 필요한 데이터를 쉽게 구성할 수 있고 변환 과정에서 유효성 검사를 수행할 수 있다는 장점을 가진다. 그러나 비지니스 로직과 혼재되어 코드의 가독성과 유지보수성이 떨어지고 재사용이 어렵다는 단점이 있다.
우리 프로젝트에서는 레이어간의 명확한 역할 분리와 재사용성을 고려하여 서비스에서 dto를 반환하기로 결정했다. 또한 서비스에서 변환작업을 수행하여 dto를 반환하는 것이 더욱 일반적인 구현이라고 한다.