Files
llm-wiki/raw/company-tech-blogs/explicit-architecture-ddd-hexagonal-cqrs-hgraca.md

8.4 KiB

title, source_type, url, archive_url, related_branches, related_projects, tags, created, last_reviewed
title source_type url archive_url related_branches related_projects tags created last_reviewed
company-tech-blog / Explicit Architecture — DDD, Hexagonal, Onion, Clean, CQRS 통합 (Herberto Graça) company-tech-blog https://herbertograca.com/2017/11/16/explicit-architecture-01-ddd-hexagonal-onion-clean-cqrs-how-i-put-it-all-together/
feature-application-query-bypass-contract
ca-skeleton
architecture
hexagonal
cqrs
query-handler
read-model
application-service
ddd
clean-architecture
ca-skeleton
2026-06-04 2026-06-04

Explicit Architecture — DDD, Hexagonal, Onion, Clean, CQRS 통합 (Herberto Graça)

Layer: raw/company-tech-blogs/ — Herberto Graça 의 "DDD, Hexagonal, Onion, Clean, CQRS, … How I put it all together" (2017-11-16) 발췌. hexagonal 아키텍처에서 CQRS query handler 가 Application Service (Use Case) 를 어떻게 다루는지의 대표적 설명.

출처 신뢰도: engineering-blog 등급 — 저자의 개인 기술 블로그. 공식 표준 아님. 그러나 DDD/hexagonal/CQRS 통합 설명에서 커뮤니티에서 자주 인용되는 article.

Parent / 활용 branch (필수)

Branch 이 자료가 정당화하는 결정
raw/branch-notes/feature-application-query-bypass-contract D2 (use-case layer ceremony 의 bypass — CQRS query handler 가 Application Service 를 거치지 않고 직접 optimized query 를 실행하는 패턴) 의 architectural reference. query side 가 "optimized query that will simply return some raw data" 로 작동하는 설계 근거

출처 / Source

왜 저장했는지 / Why archived

ca-tmpl 의 alternative 3 (CQRS query handler pattern) 의 architectural reference. Graça 는 hexagonal + CQRS 통합 설명에서 query handler 가 Application Service 와 다른 역할을 한다는 것을 명시적으로 설명. 특히 "The Query object will contain an optimized query that will simply return some raw data" 는 query side 가 domain aggregate 로딩 없이 직접 DTO 반환이 가능함을 시사.

핵심 인용 / Key quotes (verbatim)

[§CQRS query side — query object] "The Query object will contain an optimized query that will simply return some raw data to be shown to the user."

[§Application Services — role definition] "Application Services (also known as workflow services, use cases, or interactors) are used to orchestrate the steps required to fulfill the commands imposed by the client."

[§Application Services — typical steps] "1. use a repository to find one or several entities; 2. tell those entities to do some domain logic; 3. and use the repository to persist the entities again."

[§Command/Query Bus without separate bus] "Controllers can depend on Query objects [directly], distinct from Application Services."

[§DTO for view] "That data will be returned in a DTO which will be injected into a ViewModel."

Claims Extracted / 추출된 주장

Claim ID Claim (이 자료가 직접 말하는 것) Evidence quote Strength Applies to Does not prove
HGRACA-CQRS-C1 CQRS query side 에서 Query object 는 optimized query 를 담고 user 에게 보여줄 raw data 를 반환하도록 설계됨 — 도메인 aggregate 조작 없이 단순 데이터 반환 [§CQRS query side] "The Query object will contain an optimized query that will simply return some raw data to be shown to the user." engineering-blog CQRS query side 설계 — query handler 가 Application Service 를 거치지 않는 패턴 "모든 읽기가 Use Case Application Service 를 거칠 필요 없다" 는 공식 표준이 아님 — engineering-blog 등급의 저자 설계 의견
HGRACA-CQRS-C2 Application Service (Use Case, Interactor) 의 역할은 command 를 오케스트레이션 — entity 를 repository 로 find, domain logic 실행, repository 로 persist 하는 3단계 [§Application Services] "Application Services...are used to orchestrate the steps required to fulfill the commands imposed by the client." + "1. use a repository to find one or several entities; 2. tell those entities to do some domain logic; 3. and use the repository to persist the entities again." engineering-blog command side (write path) 의 Application Service 역할 정의 query side 에도 Application Service 가 필요하다는 주장의 근거는 아님 — 이 3단계는 command 를 대상으로 명시
HGRACA-CQRS-C3 query side 에서 반환되는 데이터는 DTO 형태로 ViewModel 에 주입됨 [§DTO for view] "That data will be returned in a DTO which will be injected into a ViewModel." engineering-blog CQRS query side 반환 타입 — application layer 가 JPA entity 를 직접 반환하지 않음 DTO 가 반드시 별도 record/class 여야 한다는 강제는 아님 — interface projection 도 DTO 패턴의 변형으로 간주 가능
HGRACA-CQRS-C4 Query Bus 없는 구조에서 Controller 가 Query object 에 직접 의존 하는 패턴이 제시됨 — Application Service 를 거치지 않는 thin read path 의 구조적 근거 [§Without Command/Query Bus] "Controllers can depend on Query objects [directly], distinct from Application Services." engineering-blog Command/Query Bus 를 별도 도입하지 않는 단순 CQRS 구현 Controller 가 Query object 에 직접 의존해도 hexagonal 의 transport 타입이 application layer 에 leak 해선 안 된다 는 제약은 본 인용이 직접 다루지 않음

Usage Boundaries / 적용 경계

  • 이 자료가 직접 증명하는 것:
    • HGRACA-CQRS-C1: query side 가 "optimized query + raw data return" 으로 작동할 수 있다는 설계 제안
    • HGRACA-CQRS-C2: Application Service 의 3단계 오케스트레이션은 command path 에 명시적으로 귀속
    • HGRACA-CQRS-C3: query side 반환 타입은 DTO (domain entity 가 아님)
    • HGRACA-CQRS-C4: Controller → Query object 직접 의존 패턴 (bus 없는 CQRS)
  • 이 자료가 증명하지 않는 것:
    • hexagonal 아키텍처에서 "thin read path" 에도 transport type (HTTP, gRPC) 이 application layer 에 leak 하지 않아야 한다는 설계 제약 — Graça 의 diagram 은 이 경계를 명시하지만 본 발췌 인용에는 포함되지 않음
    • Query object 또는 query handler 를 ArchUnit 으로 정적 강제하는 방법
    • Spring Boot 환경에서 query handler 를 어느 Gradle module 에 배치하는지
    • transaction 없는 thin read path 의 Hibernate session 동작
  • 내 프로젝트에 적용하려면 추가 확인이 필요한 것:
    • ca-tmpl 의 thin read path 에서 @Controller (org.springframework.web) 타입이 application port 에 노출되지 않도록 query service / read port 를 어느 layer 에 배치할지 결정 (D1 의 핵심)
    • ca-tmpl 의 ArchUnit rule 이 Controller → QueryService 직접 의존을 허용할지, 또는 QueryUseCase (인터페이스) 를 항상 중간에 두도록 강제할지

메모 / Notes

  • Graça 의 글은 2017년 작성이지만 hexagonal + CQRS 통합에서 가장 자주 인용되는 레퍼런스 중 하나. 한국어 번역본도 존재.
  • HGRACA-CQRS-C1 의 핵심 의미: query 는 domain 오케스트레이션 없이 read-optimized path 로 처리 가능 → Application Service (Use Case) 를 무조건 통과할 필요가 없음을 지지. 단 engineering-blog 등급이므로 official-vendor-doc 이나 official-standard 대비 낮은 신뢰도.
  • HGRACA-CQRS-C4 에서 "Controller 가 Query object 에 직접 의존" 한다는 설명은 ca-tmpl 의 hexagonal rule (web adapter 가 application layer 를 거쳐야 함) 과 충돌처럼 보이나, Query object 가 application layer 에 위치하면 interface dependency 는 여전히 inward pointing — hexagonal violation 아님