Skip to content

Hexagonal Architecture

참고 자료

0. 들어가며

톰 홈버그의 만들면서 배우는 클린 아키텍처 에서 처음 접하였고 흥미를 느껴 개인적으로 여러번 적용해 보았고 나름 애정(?) 을 가지고 있는 아키텍처입니다. 육각형 아키텍처의 일반적인 내용에 대한 정리와 제 경험에 따른 생각을 정리해보겠습니다.


1. 아키텍처 그리고 전통적인 계층형 아키텍처

1. 마틴 파울러 - 아키텍처란?

육각형 아키텍처를 이야기하기전 먼저 아키텍처에 대한 간단한 정의가 필요합니다. 마틴 파울러의 아키텍처에 대한 정의는 아래와 같습니다. 위 링크의 영상을 참고하시면 이해가 훨씬 수월합니다.

아키텍처는 뭔가 중요한 것 (Some Important Stuff) 이다.

참 난해합니다. 조금 더 풀어서 설명하면 아래와 같습니다.

아키텍처란 지식을 공유하는 것 (Shared understanding) 이고 또한 바꾸기 어려운 것 (Hard to change) 이다. 이를 합치면 뭔가 중요한 것 (Important Stuff) 이다.

조금 더 풀었는데도 여전히 난해하기만 합니다.

마틴 파울러가 이후에 이야기 하는 아키텍처가 중요한 이유를 참고해서 이해하면 조금 이해가 더 됩니다.

아키텍처가 중요한 이유는 이를 신경쓰지 않을 때 나중에 더 힘들어지기 때문이다.

마틴은 경제적인 관점에서 아키텍처의 중요성을 강조하며 아래의 그래프로 이를 설명합니다.

Design Stamina Hypothesis

images/DesignStaminaHypothesis.png

Design Stamina Hypothesis

이 그래프는 좋은 아키텍처 (디자인)를 가지고 있으면 초기에는 개발속도가 느리지만 일정 시점 (Design payoff line) 이후에도 기능을 추가하는 속도가 항상 선형적일수 있다는 것을 보여줍니다. 마틴은 자신의 저서인 리팩토링 에서도 이 그래프를 언급하며 리팩토링을 하는 이유 역시 좋은 Design 을 유지하여 기능 추가에 따른 코스트를 선형으로 유지하기 위함이라고 하였습니다.

정리하자면 아키텍처란 개발을 일정한 속도로 할 수 있도록 해주는 뭔가 중요한 것 입니다.

물론 이런 정의에도 논쟁의 여지가 있고 다른 정의방식 역시 많지만 개인적으로 가장 와닫는 방식입니다.


그런 아키텍처에는 크게 컴포넌트 (마이크로서비스) 내부 아키텍처와 외부 아키텍처가 있습니다. 오늘 이야기할 계층형 아키텍처육각형 아키텍처는 그 중 내부 아키텍처의 한 종류입니다.

2. 계층형 아키텍처

  • 마이크로서비스의 내부 구조를 계층형으로 구성.
  • 호출은 위에서 아래로, 아래에서 위 호출 불가

images/layered-architecture.png

계층형 아키텍처의 여러가지 형태

계층형 아키텍처는 간단하지만 레이어간 호출방향에 대한 룰 외에는 정해진 룰이 없어서 확장성 측면에서 불리합니다. 특히 도메인별 참조와 컴포넌트의 너비 (Width) 에 대한 룰을 정하지 않아 흔히 이야기 하는 스파게티 코드가 되기 쉽상입니다.

JPA 와 같은 ORM 과 결합하여 사용했을 때는 영속성 레이어가 가장 아래 있다는 점 때문에 데이터 중심적인 설계로 이어지기 쉽다는 점도 계층형 아키텍처의 단점입니다. 데이터 중심적인 설계는 MSA에 적합하지 않습니다. 이를 극복하기 위해 DDD 진영에서는 Infrastructure 레이어를 도입하고 DIP 를 적극적으로 활용하는 방식으로 Data Centric 한 기존 계층형 아키텍처의 단점을 극복하고자 하였습니다.

톰 홈버그의 만들면서 배우는 클린아키텍처 를 읽고 가장 놀란 부분 중 하나가 이 DDD 관점의 계층형 아키텍처입니다. 전통적인 3-계층 (Controller, Service, DAO) 아키텍처만 익숙해져 있다가 Infrastructure 계층을 추가하고 DIP 로 의존성의 방향을 도메인 계층으로 역전시킨 이 아키텍처는 계층형 아키텍처의 빠른 개발 생산성 이라는 장점과 Hexagonal 아키텍처의 변경에 대한 유연함을 적절히 섞은 아키텍처라는 느낌을 받았습니다.

계속 DB 즉 영속성 계층을 특별한 것이 아니라 하나의 Infrastructure 일 뿐이라고 언급하는 점 도 역시 놀라운 점 중 하나였습니다.

Clean Architecture 와 Hexagonal Architecture 는 DIP 적인 컨셉을 더 강조하는 형태의 새로운 아키텍처입니다.


3. Hexagonal Architecture

Hexagonal Architecture 는 엘리스터 콕번이 제안한 아키텍쳐이고 로버트 마틴이 제안한 Clean Architecture 의 한 형태입니다.

클린아키텍처는 애플리케이션을 계층형태가 아니라 중앙을 향하는 의존성을 가진 여러 동심원 형태로 표현합니다. 원의 가장 중앙에는 애플리케이션의 가장중요한 가치 바로 도메인이 자리합니다. 그래서 클린 아키텍처를 양파 아키텍처라고도 부릅니다.

images/onion-architecture.png

양파 껍질과 같은 클린 아키텍쳐

헥사고날 아키텍처는 아키텍처를 구성하는 중요한 요소인 포트와 어댑트의 이름을 그대로 딴 Port and Adapter 아키텍처 라고도 불립니다. 추가로 클린 아키텍처와 헥사고날 아키텍처를 비교하면 클린아키텍처는 추상적인 개념이며 헥사고날 아키텍처는 클린아키텍처를 구체적으로 (패키지 구조 형태로) 구현한 인스턴스라고 볼 수 있습니다.

images/hexagonal-architecture.png

Hexagonal Architecture
  • Port
    • 포트는 바로 인터페이스입니다.
    • In-Port (Praimary Port, Driving Port)
      • 외부에서 요청해야 동작하는 포트와 어댑터를 주요소(primary)라고 하며, 포트와 어댑터에 따라 주포트 혹은 주어댑터라고도 부릅니다.
    • Out-Port (Secondary Port, Driven Port)
      • 애플리케이션이 호출하면 동작하는 포트
  • Adapter
    • 어댑터는 바로 애플리케이션이 포트를 이용해 연결되는 외부의 구현체
    • In-Adapter (Pramary Adater, Driving Adapter)
      • WebAdapter (Rest API) 가 대표적입니다.
    • Out-Adapter (Secondary Adapter, Driven Adapter)
      • PersistenceAdapter (Repository) 가 대표적입니다.

클린/헥사고날 아키텍처의 핵심은 잘 변하는 구체 기술 (HTTP, DB, 외부 시스템)의 변경이 코어 애플리케이션과 도메인에 영향을 주지 않도록 하는 것입니다. 따라서 애플리케이션, 도메인 코드를 작성할 때는 구체적인 기술에 대한 코드를 최대한 줄여야 합니다.


4. 그럼에도 고민해야 하는 내용들

1. 기술에 대한 의존

애플리케이션, 도메인 코드를 작성할 때 구체적인 기술과 관련된 코드 없이 최대한 POJO 로 작성하는 것은 헥사고날 아키텍쳐의 중요한 원칙입니다. 하지만 때로는 개발생산성의 관점에서 적절한 합의가 이루어져야합니다.

  • Jpa 를 사용할때 도메인 모델에 Jpa 의존성을 없애고자 한다면 코드 작성이 매우 번거롭습니다.
  • Spring 을 사용하면서 Spring 에 대한 의존성 노출을 막기란 쉽지 않습니다. 특히 @Transactional 없이 트랜잭션을 구현하고자 한다면 서비스 계층에서 배보다 배꼽이 더 커지는 일이 발생할 것입니다.

이런 결정에 딱히 정답은 없으며 팀적인 합의가 가장 중요하다고 생각합니다. 같은 애플리케이션/ 도메인 코드라고 할지라도 Spring 에 대한 의존을 애플리케이션 서비스에서는 허용하고 도메인 모델에서는 제한 하는 등의 유연한 결정도 개발에 도움이 된다고 생각합니다.

2. 매핑 모델

원칙적으로 각 계층 (In-Adapter, In-Port, Domain, Out-Port, Out-Adapter) 은 모두 각자 엔티티를 표현하는 모델을 가질 수 있습니다. 하지만 개발생상성이 너무 떨어진다는 단점이 있습니다. 이때 계층별 모델 및 매핑 모델을 유연하게 공유하여 사용하면 개발 생산성에 큰 도움이 됩니다. 이때도 가장 중요한 것은 의존성은 중앙 (Domain)을 향해야 한다는 것 그리고 왠만하면 도메인 모델 만큼은 외부 모델과 분리를 하는것이 좋다 라는것입니다.


Last update: February 26, 2023
Created: December 28, 2022