결정-0052: 조회와 명령의 경로를 분리하되 도구는 하나로 둔다
상태
Accepted
맥락
화면 조회를 도메인 저장소로 처리하면 화면 요구가 도메인 모델을 끌어당깁니다. 목록에 표시명이 필요하다는 이유로 엔티티에 필드가 추가되고, 그 필드는 쓰기 로직에서 아무 의미를 갖지 않습니다. 간단한 조회에서 문을 열면 그 문으로 전부 들어옵니다.
반대로 완전한 CQRS 는 읽기 전용 저장소를 따로 두고 동기화합니다. 지연과 복잡도가 함께 들어오며, 단일 데이터베이스로 충분한 규모에서는 비용만 남습니다.
세 번째 축이 있습니다. 경로를 나눌 때 도구까지 나눌 것인가입니다. 명령에 ORM 을, 조회에 SQL 매퍼를 쓰는 구성이 널리 쓰이며 각 경로에 가장 알맞은 도구를 준다는 장점이 있습니다.
결정
코드 경로만 분리하고 저장소는 하나를 유지합니다. 그리고 두 경로가 같은 영속성 도구를 씁니다.
| 경로 | 접근 수단 | 반환 |
|---|---|---|
| 명령 | 도메인 저장소 | 애그리거트 |
| 조회 | 피쳐가 소유한 조회 포트 | 화면 DTO |
명령 서비스는 조회 포트를 주입받지 않으며 ArchUnit이 강제합니다. 컨트롤러는 조회 포트를 직접 참조하지 않습니다.
검토한 대안
완전한 CQRS — 읽기 전용 저장소를 둔다
| 구분 | 내용 |
|---|---|
| 장점 | 읽기와 쓰기의 확장을 독립적으로 다룹니다 |
| 단점 | 동기화 지연이 생기고 그 지연을 화면이 다뤄야 합니다 |
| 기각 사유 | 단일 데이터베이스로 충분한 규모에서 지연과 복잡도만 얻습니다 |
경로마다 다른 도구를 쓴다
| 구분 | 내용 |
|---|---|
| 장점 | 명령에는 객체 매핑을, 조회에는 SQL 통제력을 각각 최대로 씁니다 |
| 단점 | 두 기술의 경계에서 규칙이 자라납니다. 한쪽의 미커밋 변경이 다른 쪽 조회에 보이지 않는 문제, 반영 순서 확인, 조각 재사용 범위, 명령 경로에서 조회 도구를 예외적으로 허용하는 조건이 전부 문서가 됩니다 |
| 기각 사유 | 실제 운영 문서에서 데이터 접근 규칙의 절반가량이 두 도구의 공존 때문에만 존재했습니다. 도구를 하나로 합치면 그 규칙들이 사라집니다 |
결과
화면 요구가 도메인으로 유입되는 경로가 막힙니다. 데이터 접근 규칙이 줄어들어 문서와 학습 비용이 함께 내려갑니다.
감수하는 것은 같은 질문에 두 경로가 생긴다는 점입니다. 명령 안의 중복 검사는 도메인 저장소로, 입력 중 실시간 안내는 조회 포트로 갑니다. 둘은 다른 이유로 진화하므로 나누는 것이 맞지만, 나눈 사실을 모르면 제거해야 할 중복으로 보입니다. 그래서 두 경로가 갈리는 지점을 조회와 명령 4절이 표로 고정합니다.