--- category: Dev tags: [Architecture, Design Patterns, DDD, SOLID] title: Hexagonal Architecture (Ports and Adapters) description: 도메인 로직을 외부 인프라스트럭처로부터 격리하여 시스템의 유연성과 테스트 용이성을 극대화하는 아키텍처 설계 패턴 last_updated: 2026-05-02 --- # Hexagonal Architecture ## 📌 Brief Summary 헥사고날 아키텍처(Hexagonal Architecture), 또는 **포트와 어댑터(Ports and Adapters)** 패턴은 소프트웨어의 핵심인 비즈니스 로직(도메인)을 데이터베이스, UI, 프레임워크와 같은 외부 요소로부터 완전히 격리하는 설계 방식입니다. 시스템을 내부(Inside/Domain)와 외부(Outside/Infrastructure)로 명확히 분리하며, 모든 상호작용은 정의된 인터페이스인 **포트(Port)**와 이를 구현하는 **어댑터(Adapter)**를 통해서만 이루어집니다. 이를 통해 기술 스택의 변경이 비즈니스 로직에 미치는 영향을 최소화하고, 독립적인 테스트가 가능한 견고한 시스템을 구축합니다. --- ## 📖 Core Content ### 1. 핵심 원리: 의존성 역전 (DIP) 전통적인 계층형 아키텍처(Layered Architecture)는 상위 계층이 하위 계층(특히 DB나 외부 라이브러리)에 직접 의존하여 기술적 변경에 취약했습니다. 헥사고날 아키텍처는 **의존성 역전 원칙(Dependency Inversion Principle)**을 극한으로 활용하여, 도메인과 인프라 모두가 추상화된 인터페이스(포트)에 의존하게 만듭니다. ### 2. 주요 구성 요소 * **도메인 (Inside):** 애플리케이션의 핵심 비즈니스 로직과 규칙을 포함하는 순수 코드 영역입니다. 외부 프레임워크나 데이터베이스 기술에 대한 지식이 전혀 없는 상태로 유지됩니다. * **포트 (Ports):** 내부와 외부를 연결하는 명세(Interface)입니다. * **입력 포트 (Inbound/Driving Ports):** 외부(UI, API 호출 등)에서 도메인 기능을 호출할 때 사용하는 인터페이스입니다. * **출력 포트 (Outbound/Driven Ports):** 도메인이 외부 자원(DB, 메시지 큐, 외부 API)에 접근해야 할 때 사용하는 인터페이스입니다. * **어댑터 (Outside):** 포트를 구체적으로 구현하거나 호출하는 인프라 계층입니다. * **입력 어댑터:** REST Controller, CLI, WebSockets 등 외부 요청을 도메인이 이해할 수 있는 형식으로 변환하여 입력 포트를 호출합니다. * **출력 어댑터:** 도메인의 요청을 받아 실제 DB(JPA, MongoDB), 외부 메일 서버, 알림 서비스 등으로 전달하는 구체적인 기술 구현체입니다. ### 3. 실전 설계 전략 (Framework Specific) * **Spring Boot (Java):** 도메인 모델을 `@Entity` 등 프레임워크 어노테이션에서 분리하여 POJO로 구성합니다. `@Configuration`을 사용하여 어댑터 구현체를 런타임에 도메인 서비스에 주입합니다. * **NestJS (TypeScript):** 모듈 시스템과 DI를 활용합니다. `Domain`, `Application`, `Infrastructure`, `Presentation` 계층을 폴더 구조로 명확히 나누고, 인터페이스 기반 프로그래밍을 강제합니다. --- ## ⚖️ Trade-offs & Caveats ### ✅ Benefits * **높은 테스트 용이성:** 외부 DB나 API 없이도 모킹(Mocking)을 통해 도메인 로직만 완벽하게 테스트할 수 있습니다. * **기술 독립성:** 데이터베이스나 메시징 시스템을 교체할 때 도메인 코드를 수정할 필요가 없습니다. * **유지보수성:** 비즈니스 규칙이 한곳에 집중되어 있어 코드 파악과 변경이 용이합니다. ### ⚠️ Challenges * **초기 복잡성:** 단순한 CRUD 앱의 경우, 수많은 인터페이스와 매핑 객체(DTO/Mapper)가 오버헤드로 작용할 수 있습니다. * **보일러플레이트:** 계층 간 데이터 변환을 위한 코드가 늘어납니다. * **학습 곡선:** 전통적인 계층 구조에 익숙한 팀에게는 패러다임 전환을 위한 비용이 발생합니다. --- ## 🔗 Knowledge Connections ### Related Concepts * [[Dependency_Inversion_Principle]]: 헥사고날 아키텍처의 기술적 토대가 되는 원칙입니다. * [[Clean_Architecture]]: 비즈니스 로직을 중심에 두는 유사한 철학의 아키텍처 패턴입니다. * [[Domain_Driven_Design]]: 헥사고날 아키텍처 내부(도메인)를 채우는 모델링 방법론을 제공합니다. * [[Dependency_Injection]]: 포트와 어댑터를 런타임에 결합하는 실무 도구입니다. ### Practical Application Contexts * **System Design:** UI나 DB를 먼저 설계하지 않고, 비즈니스 유스케이스와 포트를 먼저 정의하는 '도메인 중심' 접근을 권장합니다. * **Maintenance:** 레거시 시스템을 점진적으로 개선할 때, 외부 통신부를 어댑터로 격리하여 안전하게 로직을 추출할 수 있습니다. --- ## 💡 Adjacent Topics * [[Test_Driven_Development]]: 헥사고날의 격리성을 활용하여 테스트 중심 개발을 가속화합니다. * [[CQRS]]: 대규모 시스템에서 명령(Write)과 조회(Read) 포트를 분리하여 성능을 극대화하는 전략과 궁합이 좋습니다. * [[Microservices]]: 각 마이크로서비스 내부 아키텍처로 헥사고날을 적용하여 서비스 간 독립성을 확보합니다. --- *Last updated: 2026-05-02*