Application Service는 어디에 있는가
Application Service는 어디에 있는가
CQRS의 Command Handler 안에서 로직을 더 잘게 쪼개고 싶을 때 처음 걸리는 질문이 있습니다. 이걸 "Application Service"라고 불러도 되는가? 이건 CQRS 용어인가, DDD 용어인가, Clean Architecture 용어인가?
결론부터 말하면 Application Service는 CQRS의 구성 요소가 아니라, Clean/Hexagonal Architecture의 Application Layer에 속하는 협력 객체입니다. CQRS의 Command Handler가 필요할 때 갖다 쓰는 도구일 뿐, CQRS 자체가 요구하는 개념은 아닙니다.
Command Handler와 Application Service를 언제 나누고 언제 합칠지에 대한 실전 판단 기준은 Command Handler와 Application Service, 뭐가 다른가에서 다뤘습니다. 이 글은 그보다 한 단계 앞에서, "Application Service"라는 용어 자체가 아키텍처마다 어떤 위치를 가리키는지를 정리합니다.
각 관점에서 같은 대상을 어떻게 부르는지 나란히 놓아보면 정리가 됩니다.
CQRS 관점
Command → Command Handler → 상태 변경
Query → Query Handler → 조회
Command Handler에 모든 로직을 우겨넣지 않기 위해 내부 협력자로 분리한 것이 Application Service입니다.
Command Handler
→ Application Service
→ Repository / Domain Entity / Port 사용
Clean Architecture 관점
Application Layer는 "무엇을 할지"를 조정(orchestration)하는 역할을 합니다. 도메인 규칙은 도메인 객체가 지키고, Application Layer는 그 규칙들을 엮어서 하나의 흐름으로 만듭니다.
Application Service
→ Repository Port
→ Domain Entity Method 호출
→ Result 반환
DDD 관점
DDD는 이 레이어의 서비스를 세 갈래로 구분합니다.
| 구분 | 역할 |
|---|---|
| Domain Service | 도메인 규칙 자체. Entity/ValueObject에 넣기 애매한 순수 비즈니스 규칙 |
| Application Service | 유스케이스 흐름 조정, 트랜잭션, 저장소·외부 포트 호출, 도메인 객체 메서드 호출 |
| Infrastructure Service | DB, 외부 API, 메시지 브로커 등 기술 구현 |
여기서 실무 판단이 자주 갈리는 지점은 "이게 도메인 규칙 자체를 계산하는가, 아니면 도메인 객체를 조회해서 호출만 하는가"입니다. 예를 들어 재고를 조회해서 inventory.storeAt(...)을 호출하는 코드는, 재고 상태 전이 규칙 자체를 계산하는 게 아니므로 Domain Service가 아니라 Application Service입니다. 규칙을 계산하면 Domain, 규칙을 호출/조합하면 Application — 이 한 줄이 가장 실용적인 구분선이었습니다.
Hexagonal Architecture 관점
Hexagonal에서는 Application Service가 보통 Inbound Adapter와 Domain 사이의 UseCase 구현체, 혹은 UseCase 내부 협력 서비스로 나타납니다.
Inbound Adapter
→ Command Handler / UseCase
→ Application Service
→ Driven Port
→ Infrastructure Adapter
한 줄 정리
아키텍처 위치 : Application Layer
패턴 관점 : UseCase 내부 협력 객체 / Application Service
CQRS 관점 : Command Handler가 위임하는 내부 서비스
DDD 관점 : Domain Service가 아니라 Application Service
Hexagonal 관점 : Port를 사용해 업무 흐름을 조정하는 Application 내부 구성요소
판단 기준을 압축하면 이렇습니다.
- 도메인 규칙 자체 →
Domain Entity또는Domain Service - 유스케이스 흐름·저장소 조회·트랜잭션 전 단계 조합 →
Application Service - 외부 기술 구현 →
Infrastructure Adapter - 외부에서 호출하는 진입점 →
Command Handler/UseCase/Driving Port
즉 Command Handler 내부를 Application Service로 쪼개는 건 CQRS를 대체하는 게 아니라, CQRS Handler 내부를 Application Layer답게 정리하는 작업일 뿐입니다.
다음 글에서는 이렇게 나눈 Application Service를 언제 인터페이스로 뽑아야 하는지를 다룹니다. → 인터페이스는 언제 만들어야 하는가