Service는 어떤 dto를 반환해야 할까?
리뷰 대상 코드
33조의 코드를 보면 service에서 조회 메서드를 통해 dto를 반환합니다.
그런데 response라는 네이밍에서 유추할 수 있듯이 외부로 바로 반환되는 dto입니다.
장점
해당 화면/기능만을 로직이 완전히 분할되어 개발이 편하고 변경에 강합니다.
개발이 편하다는 것이 별 것 아니라고 생각할 수 있습니다.
하지만 간결성이나 익숙한 패턴의 사용, 일관성 있는 코딩은 생산성에 지대한 영향을 줍니다.
단점
기능이 특화되는 만큼 재사용성이 떨어집니다.
예시
33팀은 공통 플랫폼/OpenApi을 만드는 팀입니다.
DishListResponse는 아래와 같은 필드를 가지고 있습니다.
AAA 사이트에서는 해당 API로 잘 쓰고 있었습니다.
그런데 어느날 신설된 BBB 사이트에서는 영문 title 반환이 필요해졌습니다.
response이 형태가 달라진 것입니다.
단순히 engTitle만 추가하면 된다고 생각할 수 있지만, BBB 사이트를 위해 수정한 response는 AAA 사이트에도 노출된다는 것이 문제입니다.
즉 의도하지 않은 사이드 이펙트가 생김으로 인해 재사용성이 떨어집니다.
만약 지금의 구조에서 AAA 사이트에 영향을 주지 않으면서 BBB 사이트의 니즈를 만족하려면, BBB 사이트를 위한 response를 반환하는 메서드를 새로 만들어야 합니다.
이미 만들어진 response를 transform하는 것은 추천하지 않습니다.
어떻게 해야되냐?
CQRS 모델을 고려하신 것이라면 지금도 나쁘지는 않습니다.
실제로 해당 기능이 특화된 경우 지금의 구조도 좋습니다.
리소스 기반이 아닌 니즈 기반의 API 설계가 필요한 경우가 있습니다.
대표적으로는 사내 어드민에 그리드 형태의 화면을 만들 때 입니다.
이 경우 다수의 테이블을 조인하고 response를 projection하는 형태로 설계하여 repository 레벨에서부터 response를 반환할 수도 있습니다.
하지만 이것이 의도한 것이라면 좀 더 특화된 네이밍과 클래스 분리를 하는 것이 좋습니다.
재사용을 고려한다면
좀 더 리소스를 기반으로 사용하기 위한 고민이 필요합니다.
한가지 예로는 service에서는 범용 dto를 반환하고 controller에서 api에 맞는 특화 response를 만들 수 있습니다.
즉 레이어별로 input, output dto를 만들면 결합도가 낮아져 재사용성은 높아집니다.
하지만
사이드 프로젝트와 같이 기간이 한정되고 큰 요구사항의 변화가 없는 경우 재사용만을 고려하는 것은 과할 수 있습니다.
네이밍의 고민과 페어에게 로직을 설명해야되는 수고가 생깁니다.
실무에서도 마찬가지이기에 생산성과 재사용/변경의 사이에서 트레이드 오프 하셔야됩니다.
저도 실무에서는 확장성이 거의 예상되지 않는 업무는 의도적으로 구조화하지 않기도 합니다.
기타 참고 사항
CQRS 패턴
BFF (백엔드 포 프론트)
언제 올지 모르는 너무 먼 미래보다는 지금의 요건에 충실하게 만들자.
Last updated