Hexagonal Architecture
Application Core와 외부 기술을 Port와 Adapter로 분리한다.
이 문서의 목차
Overview
Hexagonal Architecture는 시스템을 위·아래 Layer가 아니라 Application 내부와 외부 세계로 나눈다. Core가 의도를 표현하는 Port를 정의하고, DB·Web·Message Broker 같은 외부 기술은 Adapter가 연결한다.
Port와 Adapter
Driving Port는 사용자가 Application에 요청할 기능을 표현하고 Driving Adapter는 REST Controller나 CLI처럼 이를 호출한다. Driven Port는 Application이 외부에 요구하는 기능을 표현하고 Driven Adapter는 JPA Repository, 외부 API Client처럼 구현한다.
flowchart LR; UI[REST / CLI Adapter] --> IN[Driving Port]; IN --> CORE[Application Core]; CORE --> OUT[Driven Port]; OUT --> DB[DB / 외부 API Adapter]
public interface RegisterMemberUseCase {
MemberId register(RegisterMemberCommand command);
}
public interface SaveMemberPort {
Member save(Member member);
}Port에는 HttpServletRequest, JPA Entity 같은 특정 기술의 Type을 노출하지 않는다. Adapter가 기술 형식과 Application 형식을 변환한다.
핵심 제약
- 외부 Actor는 정의된 Port를 통해서만 연결한다.
- Application은 구체 Adapter에 Code Dependency를 갖지 않는다.
- 어떤 Adapter를 쓸지는 Runtime Composition에서 결정한다.
- Port는 기술보다 Business Intent를 표현한다.
흔한 오해
육각형의 여섯 면에는 특별한 의미가 없다. Package를 정해진 개수로 나누는 규칙도 아니다. Hexagonal Architecture 자체는 내부 Domain Model의 구현 방식까지 강제하지 않으며, Clean Architecture나 DDD와 겹치는 개념을 동일시하지 않는다.
실무에서 발생하는 문제
- 모든 Class에 Interface를 만들어 Ceremony만 늘린다.
- JPA Entity가 Port를 넘어 Core 전체에 퍼진다.
service,repository라는 Package 이름만 바꾸고 의존 방향은 그대로다.- 단순 CRUD에도 지나치게 많은 변환 객체를 만들어 변경 비용이 커진다.
Trade-off
외부 기술 교체와 독립 Test가 중요한 복잡한 업무에는 경계가 큰 이점을 준다. 단순 CRUD나 짧게 유지할 도구에서는 Port와 Mapping 비용이 이점보다 클 수 있다. 변화 가능성이 높은 경계부터 적용한다.
Interview Questions
- Driving Port와 Driven Port의 차이는 무엇인가?
- Layered Architecture와 비교했을 때 가장 중요한 경계는 무엇인가?
- Port가 기술 Type을 노출하면 어떤 문제가 생기는가?
- Hexagonal Architecture를 적용하지 않는 편이 나은 경우는?
Related Topics
TDD 전략, JPA Entity Mapping과 연결해 경계의 Test와 Persistence 변환을 살펴본다.
SOURCE REFERENCES
이 문서의 근거
본문은 Dev Atlas 안에서 완결되며, 검증이 필요할 때만 원문을 확인할 수 있습니다.