간단한 게시판 CRUD 레이어드 아키텍처 -> 헥사고날 아키텍처 적용하기

박철현·2025년 6월 7일

Java

목록 보기
11/13

들어가기 전에

  • 아래 영상후기를 통해 클린 아키텍처, 레이어드 아키텍처, 헥사고날 아키텍처 개념 학습 후 헥사고날 아키텍처 감이 잘 오지 않아 직접 프로젝트를 만들어가며 학습한 포스트 입니다.
  • 아래 게시글에서 헥사고날 변환 예제 부분이 비워져있는데, 해당 부분을 채운 포스트입니다.

[영상후기] [10분 테코톡] 누누, 다즐의 클린 아키텍처

구현 결과

  • JPA를 활용한 간단한 CRUD 게시판 기능을 레이어드 아키텍처, 헥사고날 아키텍처로 각각 구현하였습니다.
  • 패키지

레이어드 아키텍처

  • Presentation -> Service -> Persistence 순으로 저에겐 익숙한 형태로 금방 구현했습니다.
    • Controller 요청 받음 -> Service -> Repository

패키지 구조

📦 com.example.layeredarchitecture.board
├── controller
│   └── BoardController.java    # REST 컨트롤러
├── service
│   └── BoardService.java       # 서비스 클래스 (비즈니스 로직)
├── repository
│   └── BoardRepository.java    # JPA 리포지토리 인터페이스
└── entity
    └── Board.java              # 엔티티
└── dto
    └── AllBoardResponse.java     # 게시글 전체 응답 Dto
    └── BoardCreateRequestDto.java     # 게시글 작성 요청 Dto
    └── BoardDetail.java     # 게시글 상세 응답 Dto
    └── UpdateBoardRequestDto.java     # 게시글 수정 요청 Dto

헥사고날 아키텍처

  • BoardController 라는 Adapter에서 사용자 요청을 받음
    • 필요 시 Request Mapper 이용하여 POJO 도메인 객체 Board로 변환
  • BoardService 이라는 Port(Use Case)를 사용해서 사용자 요청 처리
    • 실제로는 구현체인 BoardServiceImpl 이용
  • BoardServiceImpl 에서 BoardRepository Port 이용하여 DB 접근 및 Board 엔티티 반환
    • 실제로는 구현체인 BoardRepositoryAdapter 이용
      • 내부적으로 SpringDataBoardRepo 주입 (JPA Repository)
      • 찾아온 BoardJpaEntityBoard로 변경(JPA Entity가 도메인 Entity 의존)
  • BoardController에서 Mapper 이용하여 응답 DTO 변환 및 반환

패키지 구조

com.example.hexagonal.board
├── domain                             # Pure Domain (POJO + Port 인터페이스)
│   ├── Board.java                     # 순수 도메인 모델
│   ├── BoardService.java              # Use Case Port
│   └── BoardRepository.java           # Persistence Port
├── application                        # Use Case 구현체
│   └── BoardServiceImpl.java
└── adapters
    ├── in
    │   └── web
    │       ├── controller
    │       │   └── BoardController.java
    │       ├── dto
    │       │   ├── BoardCreateRequestDto.java
    │       │   ├── BoardDetailResponseDto.java
    │       │   └── AllBoardResponseDto.java
    │       └── mapper  # DTO <-> 순수 도메인 모델
    │           ├── BoardRequestMapper.java
    │           └── BoardResponseMapper.java
    └── out
        └── persistence
            ├── entity
            │   └── BoardEntity.java # JPA Entity
            ├── SpringDataBoardEntityRepository.java  # JPA Repository
            └── BoardRepositoryAdapter.java

이전 포스트에서 없던 추가 개념

  • 구현하다 알게된 추가 개념을 소개합니다.

Application 계층

  • Application 계층을 두어 Use Case 포트 구현한 비즈니스 흐름 담당 계층 추가
  • 도메인 포트(인터페이스)와 구현체가 분리되어 순수 도메인에 기술(트랜잭션, 검증)이 스며들지 않음

DTO & Mapper 책임 분리

  • DTO는 입력/출력 어댑터(adptes/in/web) 내에서만 사용
  • 매퍼 클래스를 별도(adapters/in/web/mapper)에 두어
    • Request DTO -> 도메인
    • 도메인 -> Response DTO 로직 명확 분리
  • 도메인 코어 에서 DTO 의존 완전 제거

구현 Repository & 회고

profile
비슷한 어려움을 겪는 누군가에게 도움이 되길

0개의 댓글