헥사고날 아키텍처

Hexagonal Architecture

방법

업무 규칙을 한가운데 두고 데이터베이스나 결제 대행사 같은 바깥 기술을 갈아 끼울 수 있는 부품으로 밀어내는 설계 방식입니다.

등장 배경

프로그램에서 가장 오래 사는 것은 업무 규칙입니다. 연간 결제는 두 달치를 깎아 준다, 팀원이 열 명을 넘으면 요금제를 올린다 같은 회사가 정한 셈법입니다. 가장 자주 바뀌는 것은 그 규칙을 둘러싼 기술입니다. 결제 대행사가 바뀌고, 데이터베이스가 바뀌고, 화면이 웹에서 앱으로 늘어납니다.

그런데 코드를 짜다 보면 이 둘이 한 덩어리로 엉킵니다. 할인 계산이 결제 대행사가 준 응답을 직접 뜯어 보는 자리에서 이뤄지고, 요금제 판단이 데이터베이스에서 값을 꺼내는 문장 사이에 끼어 있습니다.

페이지덱의 태오가 겪은 것이 그 모습입니다. 연간 결제 할인율 한 줄을 고치는 데 이틀이 들었습니다. 고치는 자체는 10분이었지만 제대로 도는지 확인하려면 컴퓨터에 데이터베이스를 띄우고 결제 대행사의 시험용 계정을 받아 연결해야 했고, 그 계정 발급이 하루 걸렸습니다. 할인 계산은 곱하기와 빼기일 뿐인데 확인하는 데 회사 바깥의 서비스 두 개가 필요했던 겁니다.

2005년에 앨리스테어 콕번이 정리한 이 방식은 순서를 뒤집습니다. 업무 규칙을 안쪽에 두고, 바깥 기술은 안쪽이 정한 약속에 맞춰 꽂히는 부품으로 만듭니다. 원래 이름인 포트와 어댑터가 뜻하는 바가 그것입니다. 안쪽이 구멍의 모양을 정하고, 바깥쪽이 거기에 맞춰 들어옵니다.

사용 절차

여섯 단계로 정리됩니다. 처음부터 이 모양으로 시작할 수도 있고, 이미 엉킨 코드를 이 방향으로 옮겨 갈 수도 있습니다.

  1. 업무 규칙만 골라냅니다. 데이터베이스 이름도 결제 대행사 이름도 한 번도 나오지 않는 코드여야 합니다. 이 덩어리를 흔히 코어라고 부릅니다.
  2. 코어가 바깥과 닿아야 하는 지점을 전부 적습니다. 데이터를 저장하고 꺼내는 곳, 결제를 맡기는 곳, 메일을 보내는 곳, 화면의 요청이 들어오는 곳 같은 것들입니다.
  3. 지점마다 포트를 정의합니다. 포트는 코어가 바깥에 무엇을 요구하는지를 업무의 말로 적은 약속입니다. "결제를 승인한다" 가 포트이고 "결제사의 결제 승인 창구를 호출한다" 는 포트가 아닙니다. 기술 이름이 약속에 들어가는 순간 다른 기술로 못 바꿉니다.
  4. 포트를 방향으로 나눕니다. 바깥이 코어를 부르는 쪽이 들어오는 포트이고 화면과 API가 여기 꽂힙니다. API 는 프로그램끼리 주고받기로 약속한 창구를 말합니다. 코어가 바깥을 부르는 쪽이 나가는 포트이고 데이터베이스와 결제 대행사가 여기 꽂힙니다.
  5. 포트마다 어댑터를 만듭니다. 어댑터는 그 약속을 실제 기술로 구현한 부품입니다. 포트 하나에 어댑터가 여럿 붙어도 됩니다. 저장소 포트에 실제 데이터베이스 어댑터와 메모리에만 담아 두는 시험용 어댑터를 따로 두는 식입니다.
  6. 의존 방향을 한쪽으로 고정합니다. 어댑터는 코어를 알아도 되지만 코어는 어떤 어댑터도 몰라야 합니다. 그래서 코어를 별도 모듈로 떼어 빌드 단계에서 바깥 라이브러리를 못 가져오게 막습니다.

적합한 상황과 한계

업무 규칙이 두껍고 오래 사는 제품에서 값을 합니다. 요금 계산, 재고 배분, 보험료 산정처럼 회사가 정한 셈법이 코드의 상당 부분을 차지하고 그 셈법이 몇 년을 가는 경우입니다. 바깥 기술을 갈아 끼울 일이 예상될 때도 마찬가지입니다. 결제 대행사 교체, 메일 발송 업체 변경, 웹에 앱을 더하는 일 같은 것들입니다.

테스트가 빨라지는 것이 곧바로 체감되는 이득입니다. 코어가 바깥을 모르면 단위 테스트를 데이터베이스 없이 돌릴 수 있습니다. 함수나 모듈 하나를 떼어 확인하는 테스트인데, 원래 한 번에 3분 걸리던 것이 3초로 줄면 하루에 돌리는 횟수가 열 배가 됩니다.

한계도 분명합니다. 규칙이 얇은 제품에는 부담만 됩니다. 받은 값을 그대로 저장하고 꺼내 보여 주는 화면이 대부분인 제품에서 이 구조를 쓰면, 포트와 어댑터라는 껍데기가 정작 안에 담긴 규칙보다 많아집니다.

기술을 자유롭게 갈아 끼울 수 있다는 기대도 절반만 맞습니다. 결제 대행사처럼 하는 일이 비슷한 것끼리는 어댑터 교체로 끝나지만, 관계형 데이터베이스를 문서형으로 바꾸는 것처럼 다루는 방식 자체가 다른 경우에는 포트의 모양도 함께 바뀝니다.

실무 용례

"그건 어댑터에서 처리하죠. 코어에 결제사 응답 형식이 들어오면 안 돼요."

특정 기술의 사정이 안쪽으로 새어 들어오는 것을 막는 말입니다.

"결제사 바꾸는 건 어댑터 하나 새로 쓰는 일이라 2주면 됩니다. 할인 규칙은 안 건드려요."

바깥 기술 교체의 범위가 어디까지인지 일정으로 답하는 자리입니다.

"이 테스트 데이터베이스 안 띄우고 돌아요. 저장소 포트에 가짜 어댑터 꽂았어요."

코어가 바깥을 모르기 때문에 가능한 일이라는 뜻입니다.

페이지덱이 결제 대행사를 바꾸기로 한 자리에서 규원이 얼마나 걸리는지 물었습니다. 태오가 2주라고 답할 수 있었던 근거가 이 구조였습니다. 바꿔야 하는 것은 결제 포트에 꽂힌 어댑터 하나뿐이고, 연간 할인과 요금제 승급 규칙은 그 대행사의 이름을 모르는 상태로 코어에 있었습니다.

같은 자리에서 한 가지가 드러나기도 했습니다. 환불 처리만은 예외라서 대행사가 보내 주는 알림의 형식이 코어 안쪽까지 들어와 있었습니다. 그 부분은 어댑터 교체로 끝나지 않고 규칙 코드를 함께 고쳐야 했고, 2주 중 나흘이 거기에 들어갔습니다.

흔한 오해

육각형이라는 모양에 뜻이 있다고 읽는 경우가 많습니다. 이름이 그렇게 붙었으니 여섯 개의 무언가가 있으리라 짐작하게 됩니다. 실제로는 아무 의미가 없습니다. 바깥과 닿는 면이 여럿이라는 것을 그리려다 보니 위아래만 있는 사각형 대신 각이 많은 도형을 쓴 것뿐이고, 붙는 면은 넷일 수도 아홉일 수도 있습니다. 기억할 이름은 포트와 어댑터입니다.

배포 단위를 정하는 선택지로 아는 것도 흔합니다. 모놀리스나 마이크로서비스와 나란히 놓인 목록에서 봤으니 셋 중 하나를 고르는 것처럼 보입니다. 하지만 앞의 둘은 한 번에 서버에 올리는 묶음을 몇 덩어리로 둘지에 대한 답이고, 이쪽은 한 덩어리 안을 어떻게 나눌지에 대한 답입니다. 층위가 다르니 함께 씁니다. 모놀리스 하나를 이 모양으로 짜는 것도, 마이크로서비스 다섯 개를 각각 이 모양으로 짜는 것도 말이 됩니다. 셋 중 하나를 고르는 문제로 다루면 배포 단위 결정과 내부 구조 결정이 한 회의에서 뒤섞여 어느 쪽도 정해지지 않습니다.

자주 헷갈리는 용어

용어무엇을 나누는가헥사고날 아키텍처와의 차이
계층형 아키텍처표현·업무·데이터 세 층으로 위아래를 쌓습니다화면에서 데이터베이스로 내려가는 한 방향이라 업무 층이 데이터 층에 기댑니다. 헥사고날은 그 방향을 뒤집어 데이터베이스를 업무 규칙 바깥의 부품으로 두기 때문에, 데이터베이스를 바꿔도 업무 코드가 그대로 남습니다

같이 보면 좋은 페이지

  • 소프트웨어 아키텍처

    이 결정이 다른 어떤 결정들과 함께 놓이는지, 배포 단위와 어떻게 갈리는지 봅니다

  • 모놀리스

    이 구조가 가장 자주 얹히는 배포 단위이고, 둘을 함께 쓰는 모양이 실무에서 흔합니다

마지막 업데이트 2026-09-16