DDD 관점의 책임 결정 - KimGyuBek/Threadly GitHub Wiki

도메인 중심 설계 관점의 책임 결정

개요

Repository를 구현하다 이런 고민이 생겼다.

"이 Repository에서는 해당 엔티티만 FROM으로 조회해야하나?"

예를 들어, 특정 사용자의 팔로워/팔로잉 수 통계를 조회하려면 users 테이블을 기준으로 데이터를 가져와야한다. 하지만 FROM users를 사용하는 쿼리를 FollowJpaRepository에 넣는게 맞는지 에 대한 판단이 필요하다.

단순한 쿼리의 위치 문제가 아니라 Repository가 어디까지 책임으로 가져가야하는가에 대한 기준과 연결된다.


고민

JPA를 이용해서 데이터를 조회할 떄는 보통 엔티티간의 매핑을 통해 도메인 구조에 맞게 탐색하도록 설계하는것이 원칙이다.

이 방식은 도메인 모델을 중심으로 데이터 일관성을 유지하고 엔티티 간 의존성을 명확하게 표현할 수 있다.

특정 사용자의 팔로워/팔로잉 수를 조회하는 쿼리의 버그를 수정하던 중 기존에 user_follows 테이블을 기준으로 조회 하던 쿼리에서 users를 기준으로 조회하는 쿼리를 사용하도록 변경했다.

이 떄, "그러면 FROM user_follows가 아닌 FROM users로 변경되었으니 기존의 FollowJpaRepository가 아니라 UserJpaRepository 로 옮겨야 하나?"라는 고민이 생겼다.

처음에는 Repository가 자신이 관리하는 엔티티만 다뤄야한다고 생각했다.

Spring Data JPA 구조상, UserJpaRepositoryUserEntity를, FollowJpaRepositoryFollowEntity를 담당하도록 설계 되어있기 떄문이다.

그래서 FROM users 쿼리가 있다면 자연스럽게 UserJpaRepository에 두는게 맞아 보였다.

하지만 이러한 설계의 어색한 점이 있었다.

예를 들어, 팔로우 통계는 단순히 사용자의 데이터를 조회하는 기능이 아니라 팔로우 관계의 수를 계산하는 로직이다.

즉 쿼리의 FROMusers이지만, 쿼리가 표현하는 의미는 Follow 도메인에 더 가깝다.

그렇다면 Repository의 기준은 엔티티가 아니라 쿼리가 수행하는 도메인의 역할과 책임이어야 하지 않을까?

결론

기존에는 JPA를 통해 엔티티를 조회할 때,

연관관계 매핑을 이용해 도메인 구조에 맞게 탐색하는것이 가장 이상적이엇다. 이 접근을 JPA가 생성하는 쿼리를 기반으로 하며, 도메인 모델의 일관성과 엔티티 객체 간 관계를 유지하기에 적합하다.

하지만 Native Query를 사용하는 경우에는 이야기가 달라진다.

이 방식은 테이블 구조에 직접 접근하므로 더 이상 엔티티 매핑 구조에 얽매일 필요가 없다.

이떄 중요한 것은 엔티티 기준이 아니라 해당 쿼리가 수행하는 역할과 의미이다.

따라서 Repository를 엔티티를 기준으로 강제할 필요가 없다고 판단했다.

오히려 도메인 책임을 기준으로 Repository를 선택하는편이 전체 구조의 응집도와 일관성을 높인다.

정리하자면,

JPA 엔티티 기반 조회는 엔티티 구조에 맞게 탐색,

Native Query 기반 조회는 쿼리의 기준 테이블이 아닌, 쿼리의 의미가 속한 도메인의 Repository에 배치

따라서 Repository도메인 책임 중심으로 유지하기로 결정했다.


정리

비슷한 고민은 ControllerService 구현에서도 있었다.

예를 들어 특정 사용자의 게시글 목록 조회 API를 구현하던 중, 게시글 관련 기능이니 당연히 PostController 안에 구현 했고 모든 엔드포인트를 /posts로 시작하도록 설계했다.

하지만 REST API 관점에서 보자면 특정 사용자의 게시글 목록 조회/posts 보다 /users/{userId}/posts가 더 자연스러운 경로였다.

이 문제를 해결하려면 @RequestMapping("/api/posts")로 전역설정했던 prefix를 제거하고,

특정 사용자의 게시글 조회 메서드만 별도로 /users/로 시작하도록 수정해야 했다.

그 과정에서 이런 의문이 생겼었다.

"경로가 다른 이 메서드를 FollowController에 두는게 맞을까?"

결국 REST 경로보다 중요한 건 Controller가 담당하는 도메인의 책임라고 결정했다.

즉, Repository에서 그랬던 것처럼

물리적 기준(테이블, URL) 보다 도메인 책임이 중심이 되어야한다는 결론에 도달했다,

이 원칙은 단순히 개인적인 결정이 아니라 **DDD의 핵심 철학과도 일치한다.

"무엇을 다루는가" 보다 "무엇에 속하는가" 로 향하는 이 설계가 도메인 주도 설계를 제대로 반영하는거라고 생각한다.


관련 문서

⚠️ **GitHub.com Fallback** ⚠️