테이블링의 NestJS 기반 오피스 서버가 3계층(Controller-Service-Repository) 구조에서 UseCase 계층을 추가한 4계층 구조로 진화한 과정을 다룬다. Service 간 의존 시 이미 DTO로 변환된 데이터만 받는 문제를 UseCase로 비즈니스 로직과 데이터 가공을 분리해 해결했다.
핵심 포인트- 기존 구조에서 Service A가 Service B를 Inject하면 이미 DTO로 변환된 데이터를 받아 원본 값을 얻지 못하는 문제가 발생했다.
- UseCase 계층을 추가해 비즈니스 로직은 UseCase가, Response DTO 변환은 Service가 담당하는 책임 분리를 구현했다.
- 4계층 구조(Controller-Service-UseCase-Repository)로 재사용성, 테스트 편의성, 책임 명확성을 모두 향상시켰다.
상세 정리- 초기 문제 발견: Service가 다른 Service를 의존할 때 이미 Response DTO로 변환된 데이터를 반환받아, 원본 데이터 접근이 불가능해 비즈니스 로직에서 필요한 값을 얻지 못하는 이슈가 생겼다.
- 근본 원인: Service가 비즈니스 로직 수행과 DTO 변환을 동시에 담당해 다른 Service에서 재사용하기 어려운 구조였다.
- UseCase 계층 역할: 순수한 비즈니스 로직을 수행하고 원본 도메인 데이터를 반환한다. Service는 UseCase 결과를 Response DTO로 변환하는 역할만 한다.
- 최종 4계층 구조: Controller(HTTP 요청/응답 처리) → Service(Response DTO 변환) → UseCase(비즈니스 로직 + 원본 데이터 반환) → Repository(DB 접근).
- 의존 문제 해결: 다른 계층에서 비즈니스 로직이 필요할 때 UseCase를 직접 Inject해 원본 데이터를 얻을 수 있게 됐다.
- 재사용성 향상: UseCase가 순수한 비즈니스 로직을 담당하므로 여러 Service에서 같은 UseCase를 재사용하기 쉬워졌다.
- 테스트 편의성: 각 계층의 책임이 명확히 분리돼 단위 테스트 작성이 쉬워졌다.
왜 읽나NestJS 백엔드에서 Service 간 의존으로 인한 데이터 가공 이슈를 UseCase 계층 추가로 해결한 실제 사례. 계층형 아키텍처 설계를 고민하는 백엔드 개발자에게 참고 자료.