#기술블로그 #백엔드 #개발 #아키텍처 #설계 #### 참고자료 [코드 사례로 보는 Domain-Driven 헥사고날 아키텍처](https://devblog.kakaostyle.com/ko/2025-03-21-1-domain-driven-hexagonal-architecture-by-example/) [Hexagonal Architecture, 진짜 하실 건가요?](https://tech.kakaopay.com/post/home-hexagonal-architecture/#server-driven-ui-적용) [당근페이 백엔드 아키텍처가 걸어온 여정](https://medium.com/daangn/당근페이-백엔드-아키텍처가-걸어온-여정-98615d5a6b06) 이번 학기에는 프로젝트를 두 개 정도 하고 있는데, 프로젝트에 새로운 기술을 적용해보고 싶다는 생각을 하다가 X에서 '헥사고날 아키텍처'를 접하게 되었다. 이 게시글에서는 (나도 공부할 겸) 헥사고날 아키텍처가 무엇인지 + 실제 사용 사례들과 함께 내가 한 생각들을 정리해보려고 한다. --- # 📓 헥사고날 아키텍처란? **Alistair Cockburn이 2005년에 제안한 아키텍처 패턴**. 다른 이름으로 **Ports and Adapters**. `intuitive understanding` **비즈니스 로직(도메인)을 정중앙에 두고, 외부 세계(DB/API/웹/메시지큐)는 전부 어댑터로 격리하라.** 도메인은 바깥 기술을 몰라야 한다. `구조` ``` [Controller] [Scheduler] [Kafka Consumer] ↓ ↓ ↓ ━━━━ Input Port (UseCase 인터페이스) ━━━━ ↓ [Domain / Service] ↓ ━━━━ Output Port (Repository 인터페이스) ━━━━ ↓ ↓ ↓ [JPA Adapter] [Redis Adapter] [Toss API Adapter] ``` - `port` 도메인이 정의하는 **인터페이스** (계약) - `adapter` Port의 **구현체** (실제 기술) - `input port(driving)` 외부가 도메인을 호출할 때 — UseCase - `output port(driven)` 도메인이 외부를 호출할 때 — Repository-ish # 💡 사용 예시 - 카카오페이 홈 & 지그재그 PDP & 당근페이 Money 사실 개념만 봐서는 감이 잘 안 온다. (붕어빵 틀 어쩌고 한다고 클래스 바로 못 만드는 것과 같은 이치) 그래서 IT 기업 테크블로그에서 헥사고날 아키텍처의 실제 적용 사례를 찾아보았다. 처음 헥사고날을 접했을 때는 무조건 적용해봐아겠다는 생각이었는데, 도입 후에 제거한 케이스도 있어서 조금 놀랐다 ;; 우선 내용을 정리한 표를 보자! ## [[#참고자료]]로 보는 도입 결과 | 회사 | 규모/특성 | 결과 | 이유 | | -------------- | ------------------ | ------------------------- | ------------------------------------------------------------------------------------- | | **카카오페이 홈** | 24개 서버 연동, SDUI 조립 | **도입 후 제거** (8000줄 삭감) | 도메인이 모호 — "외부 데이터 조합 + 렌더링(server-driven UI)"이 본질. 연동 인터페이스로 이미 외부 변경 방어 중. 재사용 모듈 없음 | | **지그재그 PDP** | 20개 MSA 연동, SDUI | **1년+ 성공 운영** | 도메인 경계 명확. | | **당근페이 Money** | 금융/결제/송금 | **Layered→Hexa→Clean** 진화 | 금융 도메인 자체가 명확하고 강함. 팀 커지니 "사람 규율"보다 "구조 강제"가 필요 | 그렇다면, ## 같은 패턴인데 왜 어디는 유지하고, 어디는 제거했을까? 나는 뭐 잘 모르고 안 해봤지만;; 세 글을 읽으면서 헥사고날을 도입하기 전 이런 질문을 해야 한다고 느꼈다. 헥사고날까지 도입하며 **"보호할 도메인 로직이 있는가?"** - 카카오페이 홈: "외부 데이터 → SDUI 변환"이 일의 전부 → 도메인이 사실상 Adapter 로직 → 헥사고날의 의미가 퇴색될 수밖에 없는 구조였다 - 지그재그 PDP: 애그리거트(Catalog/Shop/Price/Review)별로 도메인 규칙 있음 → 보호 가치 있음! - 당근페이 Money: 지갑/송금/입출금은 돈 다루는 명확한 도메인 → 보호 필수! 즉, 도메인을 정중앙에 두고 바깥 기술을 모르도록 할 것이라면 그 도메인은 무조건 명확한 경계를 가져야 한다는 것이다... 여기서 볼 수 있는 장단점도 정리할 수 있었다. # ✅ 헥사고날의 장점 1. **도메인-인프라 분리** — 외부 기술(Redis→Valkey, PG사 교체) 변경이 도메인에 안 퍼짐 2. **Mock 테스트 단순** — `@SpringBootTest` 없이 순수 단위 테스트 (10배 빠름) 3. **유스케이스 재사용** — 같은 UseCase를 Web API / 배치 / Consumer에서 재사용 (당근페이) 4. **팀 커질수록 구조가 규율 강제** — "잘 지키자" 관습 의존 탈피 (당근페이 핵심 동기) # ⛔ 헥사고날의 단점 카카오페이 기술블로그를 보면 더 잘 확인할 수 있다. 1. **보일러플레이트 폭증** — 기능 1개에 Port/Adapter/DTO/Mapper 여러 파일. 40개 out Port면 신규 기능 하나에 다 건드려야 함 2. **도메인 정의가 모호하면 Port 경계도 모호** — 결국 외부 API 응답이 Port 모양을 결정하는 "주객전도" 3. **DTO 매핑 지옥** — Layer마다 DTO, Mapper 계속 작성 4. **학습 곡선** — 신규 입사자 온보딩 비용. 팀원마다 이해 다르면 오히려 다양성 폭발 (카카오페이 지적) 5. **재사용 컴포넌트가 없으면 효용 급락** — API 서버 하나만 있으면 굳이 모듈 분리 필요 없음 (카카오페이) # 📋 도입 체크리스트 - [ ] **도메인 모델이 명확한가?** (DDD 준하는 수준) - [ ] **의존성이 "넓지" 않은가?** — 로직 대부분이 외부 API 조합이면 Port가 비대해짐 - [ ] **코어 모듈을 2개 이상 컴포넌트(API/Batch/Consumer)가 재사용하는가?** 셋 다 YES여야 권장되며, 하나라도 NO면 레이어드 + 관심사별 패키징이 나을 가능성이 높다. 특히 빠르게 스프린트식으로 진행되는 프로젝트에서는 위 단점들 중 **보일러플레이트 문제와 학습 곡선 문제**에 대해서도 더 생각해봐야 하지 않나 싶다. 다음 글은 진행하고 있는 각 프로젝트가 이 '도입 체크리스트'를 만족하는지 확인해보려고 한다... 끝 ![](https://media.tenor.com/WzmgDtpGCSIAAAAM/goodbye-but-keep-on-praying-goodbye.gif)