Hexagonal Architecture
- 애플리케이션의 핵심 비즈니스 로직을 외부 시스템이나 기술적인 구현으로부터 분리하여 유연하고 시스템을 구축하는 것을 목표로 하는 아키텍쳐 중 하나
왜 나오게 되었을까?
과거에는 인프라와 도메인이 붙어있는 구조였지만 점차 비즈니스 로직이 복잡해지면서 인프라는 신경쓰지 않으면서 비즈니스 로직에 집중하고자 하는 니즈에서 출발하게 됨.
비즈니스 로직과 인프라를 분리하고자하는 노력은 꾸준히 발전해왔음.
그 노력이 바로 클린 아키텍쳐!
클린 아키텍쳐?
비즈니스 로직과 인프라에 대한 디펜던시를 없애는 컴포넌트 설계방식
유즈 케이스 추상화 레이어를 통해 전체적인 흐름을 제어하며
의존성은 외부에서 내부로만 존재한다.(의존성 규칙)

[출처]https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
[출처]https://techblog.woowahan.com/2647/
하지만 클린 아키텍쳐는 개개인의 생각이나 구현이 다를 수 있어 헷갈릴 요소가 있다.
헥사고날 아키텍쳐는 구조와 구현이 클린 아키텍쳐에 비해 단순하고 클린 아키텍쳐와 마찬가지로 의존성 규칙을 따른다.

주요 컴포넌트
- Adapters/Ports
- Application Services
- Domain Model
Adapters
- 포트를 통해 인프라와 실제로 연결하는 부분을 담당하는 구현체
- Driving Adapter (프라이머리 어댑터)
사용자의 입력을 받아 포트(Port)를 통해 애플리케이션 서비스에 전달하는 역할
예시: Controller, CLI(Command Line Interface), Web API, GraphQL 등
- Driven Adapter (세컨더리 어댑터)
애플리케이션 서비스가 요청한 작업을 실제로 수행하는 역할
예시: Repository(데이터베이스 접근), Message Queue, HTTP Client 등
Ports
- 인터페이스 정의만 존재
- DI(Dependency Injection, 의존성 주입)을 위한 추상화
- 입력 포트 (Inbound Port)와 출력 포트 (Outbound Port)가 있다.
Application Services
- Adapter를 주입받아서 도메인 모델과 어댑터를 조율? 관리하는 부분
- 비즈니스 로직이 실행되기 위해서 필요한 내용들을 담당해준다.
Domain Model
- 모든 엔티티에 대한 변경은 이곳에서만 실행.(외부에서는 실행되면 안됨)
- 이곳에서 일어나는 엔티티에 대한 변경을 = 비즈니스 로직 이라고 함.
- 외부 의존성이 없어야 하는 것이 원칙!
- 그러나! 레포지토리의 경우에는 예외적으로 포트(인터페이스)를 이용해 어댑터를 주입받아서 사용할 수 있음
- Why?
원칙적으로 도메인은 외부 의존성이 없어야 하지만, 데이터베이스의 존재를 완전히 무시할 수 없기 때문에 Repository 포트를 통해 의존성을 주입받는다.
즉, 도메인 내부에서 직접 DB에 접근하는 것이 아니라, Repository Port(인터페이스)를 통해 데이터를 읽어오고 저장하는 방식으로 의존성을 최소화한다.
결론
왜 헥사고날/클린 아키텍쳐를 사용하는 것이 좋은가?
- 명확한 관심사의 분리
- 외부와의 연결에 문제가 된다면? -> 어댑터
- 인터페이스 문제는? -> 포트
- 트랜잭션 관리나 이벤트 처리를 하고싶다면? -> 애플리케이션 서비스
- 비즈니스 로직의 문제는? -> 도메인 모델
각각 분리가 되어 있다!!
- 쉬운 테스트
- Port 기반 모킹(mocking)을 통해 어댑터 없이 테스트 가능
- 도메인 로직이 의존성이 없으므로, 순수한 단위 테스트 가능
- 각각 연결되어 있는 부분만 테스트하면 된다.
즉, 자기 역할만 테스트를 하면 된다!!
mocking 모킹이란?
테스트 대상 객체가 의존하는 외부 객체를 가짜(Mock) 객체로 대체하여 테스트를 수행하는 것