본문 바로가기

Web/웹 상식

[Web] 헥사고날 아키텍처 알아보기

각종 블로그와 문서들을 보고 정리한 내용입니다. 정확한 정보가 아닐 수 있습니다. 유의 바랍니다.

Hexagonal Architecture이 뭘까?

포트와 어댑터 아키텍처헥사고날 아키텍처로 더 잘 알려져 있는 것 같습니다.

어떠한 아키텍처이길래 포트와 어댑터로 불리는 걸까요? 포트와 어댑터 아키텍처 구조를 간단하게 그려보았습니다.

포트와 어댑터 아키텍처(헥사고날 아키텍처)

위와 같은 구조로 구성하는 것이 포트와 어댑터 아키텍처이고 중심 부분이 헥사 모양으로 구성되어서 헥사고날로 불리고 있습니다. 엔티티를 중심으로 외부로는 포트를 통해서 노출되어 있고 각 포트에 어댑터들이 붙어서 작동하는 구조입니다.

 

주황색으로 분리해 둔 것은 아래의 코드에서 패키지 구조를 표현하기 위해 추가한 경계입니다. (코드로 바로가기)

 

목표

이 아키텍처의 목표는 인터페이스나 기반 요소와 서비스를 담당하는 핵심 코드를 확실하게 분리하고 관리하는 것을 목표로 하고 있습니다.

이를 통하면 사용자의 새로운 요청 사항이 있을 때 장점이 있습니다. 만약 새로운 요청에 따라 인터페이스가 변경되거나 기반 요소들이 변경되더라도 애플리케이션의 중심 비즈니스 로직들은 변경이 없거나 최소한으로 영향을 받도록 할 수 있습니다.

 

그렇다면 실제로 사용해보기 위해 코드로 위 그림의 구조를 구현해보겠습니다.

 

코드로 구현해보기

개발 환경

  • SpringBoot 2.x
  • JPA
  • H2 DB

패키지 구조

패키지 구조

패키지의 큰 틀에서는 adapter, application, domain으로 분리됩니다. 각각 이 글 상단의 그림에서 주황색 박스와 대응됩니다. 그리고 각각 디렉토리의 내부는 아래와 같습니다.

 

  • adapter
    • in : 사용자의 요청을 받는(in) 어댑터가 포함됩니다.
    • out : DB로 요청을 보내는(out) 어댑터가 포함됩니다. JPA도 DB에 대한 어댑터라고 볼 수 있으므로 Repository 관련 파일도 여기에 포함했습니다. 그래서 application > outport에서 바로 JPA interface를 호출해도 되겠지만 명확하게 하기 위해 어댑터(CalculateLogAdapter)를 한 단계 추가했습니다.
  • application
    • port
      • in : 사용자를 통해 들어온 요청을 받고(in) 출력을 내보냅니다.
      • out : 애플리케이션쪽에서 요청을 보내는(out) 쪽 포트입니다. 애플리케이션이 요청을 보내는 곳인 Persistence Adapter와 이곳의 포트를 통해 통신하게 됩니다.
    • service : 핵심 로직들이 작성되는 서비스들이 포함됩니다.
  • domain : 핵심 로직의 중심이 되는 도메인이 포함됩니다.

주요 코드 부분

Web Adapter

Web Adapter 부분

웹 어댑터 부분은 Spring MVC 구조에서 컨트롤러에 해당합니다. 사용자가 요청을 보내고 받는 부분입니다. 애플리케이션의 in port를 주입받아서 사용합니다.

 

Application Use Case

use case

사용자 혹은 외부 서비스에서 애플리케이션에 요청할 수 있는 내용들을 포함한 인터페이스입니다. 각 어댑터에서는 이 인터페이스에 있는 메서드를 통해 정보를 요청할 수 있습니다.

 

핵심 로직

핵심 로직을 포함하는 application > service 부분입니다. Spring MVC의 서비스 부분하고 동일합니다. 이 부분은 외부의 요청사항들이 변경되더라도 변경이 없도록 관리해야 합니다.

 

Application Out Port

애플리케이션의 out port 부분입니다. 이 부분을 통해서 Repository로 요청을 보냅니다.

 

Adapter Out Port

이 부분은 DB와 통신을 할 어댑터입니다. 이 어댑터는 필요 없을 수 있습니다. JPA를 사용한다면 JPA Interface가 어댑터 역할을 해주는 구조처럼 보이니까요. 하지만 확실한 구조 구현을 위해 추가했습니다.

 

정리

포트와 어댑터 아키텍처(헥사고날 아키텍처)를 잠깐 살펴본 느낌으로는 확실히 핵심 로직을 변경하지 않고 요청 사항에 맞추는 책임을 어댑터 쪽, 즉 요청을 하는 쪽으로 책임을 옮긴 느낌입니다. 의존성 역전이 잘 보인다는 느낌입니다.

이전에 실무 서비스에서 여러 요청사항에 맞춰 서비스 로직을 수정하다 보니 분기가 자꾸 생겨나고 그에 따라 로직이 너무 복잡해지는 느낌이 강했는데 헥사고날 아키텍처를 사용하면 최대한 비즈니스 로직을 간결하고 깔끔하게 가져갈 수 있을 것 같습니다.

 

분명 레이어드 아키텍처의 단점을 보완하기 위해 나온 아키텍처의 느낌은 있기 때문에 실무에 적용한다면 아주 좋을 것 같습니다.

 

하지만 또 한편으로는 위의 아주 간단하고 귀찮음이 많이 보이는 코드를 작성하면서도 어댑터와 포트를 호출하는 것이 아닌 서비스나 레포지토리를 호출하고 싶어 진 적이 한두 번이 아닙니다. 코드도 많아지고 레이어드 구조보다는 조금 더 귀찮은 건 사실인 것 같습니다.

 

참고

 

지속 가능한 소프트웨어 설계 패턴: 포트와 어댑터 아키텍처 적용하기

2022-LINE-engineering-site

engineering.linecorp.com

 

반응형