헥사고날 아키텍처 적용해보기
2. 프로젝트에 아키텍처 적용하기
저번 포스팅에서는 헥사고날 아키텍처가 무엇인지 이론적인 개념에 대해 다루었다면, 이번 포스팅에서는 실제로 개인 프로젝트에 헥사고날 아키텍처를 적용해 본 실무적인 내용을 다룬다.
패키지 구조 구성
기존 3-Layer 아키텍처에서의 패키지 구조는 서비스 도메인 단위로 나뉘어졌다. 예를 들어 다음과 같았다고 가정해보자
┌ user
├── controller
├── service
├── model
├── repository
|
├ board
├── controller
├── service
├── model
└── repository
헥사고날 아키텍처에서는 서비스 도메인 단위로 나누지 않고, 보통 port, adapter로 패키지를 구성한다. 패키지 구조를 port, adapter 패키지로 나눈 예제는 대략 다음과 같이 작성할 수 있겠다.
┌ adapter
├── in
├────── rest
├────── view
├── out
├────── application
├────── persistence
|
├ application
├── port
├────── in
├────── out
├── service
└ infra
실제 개인 프로젝트에 헥사고날 아키텍처를 적용한 패키지 구조의 모습은 대략 아래와 같은 형태로 이루어졌다.
┌ adapter
├── in
├────── rest
├────────── BoardApiController.java
├────────── UserApiController.java
├────── view
├────────── BoardController.java
├────────── UserController.java
├── out
├────── persistence
├────────── entity
├────────────── Board.java
├────────────── User.java
├────────── repository
├────────────── BoardRepository.java
├────────────── UserRepository.java
├────── BoardAdapter.java
├────── UserAdapter.java
|
├ application
├── port
├────── in
├────────── dto
├────────────── BoardDto.java
├────────────── UserDto.java
├────────── BoardCommandUseCase.java
├────────── BoardSearchUseCase.java
├────────── UserCommandUseCase.java
├────────── UserSearchUseCase.java
├────── out
├────────── BoardPort.java
├────────── UserPort.java
├── service
├────── BoardService.java
├────── UserService.java
├ infra
├── BoardJpaRepository.java
├── BoardRepositoryImpl.java
├── UserJpaRepository.java
└── UserRepositoryImpl.java
3-Layer 계층 구조와 비교했을 때 새롭게 등장한 구성 요소로는 Adapter, Port, UseCase 정도가 될 것 같다. 각 요소들에 대해 간략한 설명을 하자면 다음과 같을 수 있겠다.
- Adpater
- in: 사용자 인터페이스 (REST API 등)
- out: 데이터베이스 관련 구성요소 (Entity, ORM, JPA 등)
- UseCase
- Adapter의 in 으로부터 입력 받는 역할을 하는 인터페이스로, 비즈니스 로직을 구현하는 Service 클래스에서 해당 인터페이스 기능을 구현한다.
- UseCase의 명세는 최대한 작은 범위로 구성하며 입력 유효성 검증은 하지 않고, 비즈니스 규칙만 검증한다.
- Port
- Adapter의 out 과 연결되는 역할
느낀점
아직 헥사고날 아키텍처에 대해 완벽히 다룰 수 있는 정도는 아니지만 실제 프로젝트에서 적용해본 것으로 비즈니스 계층과 외부 연결과의 의존성을 분리하는 부분에 대해 확실히 공부가 되었고, 생각보다 다양한 아키텍처 구성 방식이 있구나 하는 걸 깨닫게 되었다.
물론 계층형으로 구성된 커다란 서비스를 헥사고날 아키텍처로 리팩토링하는 건 비용적인 측면에서 힘든 일이 되겠지만, 신규 프로젝트를 구현할 때부터 헥사고날 아키텍처로 구조를 잡고 개발한다면 확장성인 측면에서 분명한 이익이 있을 것 같다고 생각했다.