#기술블로그 #백엔드 #개발 #아키텍처 #설계
#### 참고자료
[코드 사례로 보는 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면 레이어드 + 관심사별 패키징이 나을 가능성이 높다.
특히 빠르게 스프린트식으로 진행되는 프로젝트에서는 위 단점들 중 **보일러플레이트 문제와 학습 곡선 문제**에 대해서도 더 생각해봐야 하지 않나 싶다.
다음 글은 진행하고 있는 각 프로젝트가 이 '도입 체크리스트'를 만족하는지 확인해보려고 한다...
끝
