Skip to end of metadata
Go to start of metadata

You are viewing an old version of this content. View the current version.

Compare with Current View Version History

« Previous Version 2 Current »

핵심적인 카테고리

  1. Enums

    • 비즈니스 로직과 관련된 상수값들을 정의.

    • 예: 도메인 내 상태 값, 코드 값 등.

  2. Domain

    • 핵심 비즈니스 로직 및 규칙을 포함.

    • Entity, Value Object, Aggregate, Domain Service 등이 포함될 수 있음.

  3. DTO

    • 외부와 데이터를 교환하기 위한 객체.

    • 요청 및 응답용 RequestDTO, ResponseDTO 등을 포함.

  4. Service

    • 응용 계층(Application Layer)의 비즈니스 로직을 처리.

    • Facade, Application Service, Domain Service를 분리하여 명확히 관리 가능.

  5. Repository

    • 도메인 객체의 영속성을 관리.

    • JpaRepository 또는 커스텀 Repository 인터페이스와 구현체.

  6. Controller

    • 사용자 요청을 받아서 응답하는 입출력 계층.

    • REST API 혹은 웹 소켓 컨트롤러를 포함.

  7. Configuration

    • 애플리케이션 전반의 설정과 구성.

    • Bean 등록, 외부 라이브러리 설정.

  8. Utils/Helper

    • 공통적으로 사용되는 유틸리티 함수와 헬퍼 클래스.

    • 비즈니스 로직과 직접적인 관련이 없는 범용 도구들.


추가적으로 고려할 수 있는 카테고리

  1. Adapter

    • 외부 시스템과의 통합을 담당.

    • 예: API 통신, 메시징 시스템(Kafka, RabbitMQ 등)과의 연계.

    • 헥사고날 아키텍처에서는 Port와의 인터페이스를 구현.

  2. Port

    • 애플리케이션이 외부와 통신하는 인터페이스.

    • Inbound Port: 사용자의 요청을 받아들임 (예: Service 인터페이스).

    • Outbound Port: 외부 시스템에 요청을 보냄 (예: Repository 인터페이스).

  3. Exception

    • 커스텀 예외를 정의하여 예외 처리를 중앙 집중화.

    • 예: 비즈니스 예외, 어플리케이션 예외.

  4. Mapper

    • 도메인 객체와 DTO 간 변환 로직을 포함.

    • MapStruct와 같은 라이브러리를 활용하거나 수동으로 매핑 로직 작성.

  5. Event

    • 도메인 이벤트를 처리하거나 발행.

    • 이벤트 퍼블리싱 또는 핸들링과 관련된 클래스.

  6. Validation

    • 입력 데이터의 검증 로직.

    • Validator 클래스 또는 애노테이션 기반의 검증.

  7. Scheduler/Batch

    • 정기적으로 실행되는 작업 처리.

    • 스케줄링 또는 배치 작업 관련 클래스.

  8. Interceptor/Filter

    • 요청/응답 처리 파이프라인에 추가되는 처리 로직.

    • 예: 인증, 로깅, 권한 확인.

  9. Integration

    • 외부 서비스와의 연동 테스트 및 모의 구현(Mock).

    • API, 데이터베이스, 메시지 브로커와의 통합 코드.

  10. Test

    • 단위 테스트(Unit Test), 통합 테스트(Integration Test), E2E 테스트.

    • 테스트 전용 설정 및 Mock 구현.


예시 구조

src
├── adapter
├── application (service, use case)
├── configuration
├── controller
├── domain
│   ├── enums
│   ├── entity
│   ├── valueobject
│   └── service
├── dto
├── event
├── exception
├── mapper
├── port
│   ├── inbound
│   └── outbound
├── repository
├── scheduler
├── utils
└── test


특히 중요한 점

  • 헥사고날 아키텍처에서는 AdapterPort의 역할을 명확히 구분하고, 도메인 계층과 의존성을 최소화해야 합니다.

  • 공통 기능(Utils, Helper)은 특정 도메인이나 계층에 의존하지 않도록 설계해야 합니다.

  • 필요하다면 각 계층을 더 세분화하거나 프로젝트 특성에 맞게 조정할 수 있습니다.

JPA 기반 추가 고려사항

  1. Entity

    • JPA에서 사용하는 도메인 엔티티 클래스.

    • 애너테이션(@Entity, @Table 등)을 사용하여 데이터베이스와 매핑.

    • 일반적으로 Domain 계층에 포함되지만, 명확한 분리를 원하면 별도로 관리.

  2. Repository

    • JPA Repository 인터페이스.

    • Spring Data JPA의 기본 Repository 인터페이스를 확장하거나, 커스텀 메서드 정의.

  3. Specification/Criteria

    • 복잡한 쿼리를 생성하기 위한 JPA의 Criteria API 또는 Specification 클래스.

    • 데이터 검색 로직을 깔끔하게 분리.

  4. Entity Listener

    • JPA 엔티티와 관련된 이벤트(@PrePersist, @PostLoad 등)를 처리하는 리스너 클래스.

  5. Mapping Layer

    • 도메인 객체(Entity)와 DTO 간 변환.

    • MapStruct와 같은 라이브러리 또는 수동 매핑 구현.

    • 명확한 책임 분리를 위해 도메인 계층 외부에 위치.


구조 예시

src
├── adapter
│   ├── persistence
│   │   ├── repository (JpaRepository 확장)
│   │   ├── entity (JPA Entity 클래스)
│   │   └── criteria (Specification, Criteria API 관련)
│   ├── api
│   └── messaging
├── application
│   ├── service (Application 서비스)
│   └── usecase (유스케이스별 클래스)
├── domain
│   ├── entity (도메인 엔티티 - JPA 의존성 제거 가능)
│   ├── valueobject
│   └── service (도메인 서비스)
├── dto
├── port
│   ├── inbound
│   └── outbound (Repository 인터페이스 포함)
├── configuration
├── event
├── exception
├── mapper
├── utils
└── test


주요 포인트

  1. JPA Entity 분리:
    JPA Entity는 Domain에 포함될 수 있지만, 데이터베이스 중심 설계와 도메인 중심 설계를 분리하려면 AdapterPersistence 디렉터리에 위치시킬 수 있습니다.

  2. Repository와 Port 연결:
    JPA Repository는 Outbound Port의 구현체로 위치하며, 도메인 서비스에서 Repository 인터페이스만 의존하도록 설계합니다.

  3. Entity Listener 및 이벤트:
    JPA의 @EntityListeners를 활용하여 영속성 관련 이벤트를 처리할 수 있습니다.

  4. Specification 사용:
    복잡한 쿼리를 작성해야 하는 경우, JPA의 Specification 또는 Criteria API를 별도의 클래스로 구성해 Repository 로직을 깔끔하게 유지합니다.

Feature 기반 분리 시 주요 원칙

  1. Feature 단위로 독립성 유지

    • 각 Feature는 자신의 도메인 모델, 애플리케이션 로직, 데이터 저장소를 독립적으로 관리.

    • 다른 Feature와의 통신은 API나 메시지 큐를 통해 수행.

  2. 공통 기능 최소화

    • 각 Feature에서 중복을 줄이기 위해 공통 모듈(common 또는 shared)을 생성할 수 있지만, 남용하지 않도록 주의.

    • 예: 공통 유틸리티, 인증/인가 모듈.

  3. 도메인 중심 설계

    • 각 Feature는 자신의 도메인과 유스케이스에 맞는 설계를 유지.

    • 다른 Feature에 의존하지 않도록 설계.


Feature 기반 구조 예시

src
├── feature-a
│   ├── adapter
│   │   ├── api
│   │   ├── persistence
│   │   └── messaging
│   ├── application
│   │   ├── service
│   │   └── usecase
│   ├── domain
│   │   ├── entity
│   │   ├── valueobject
│   │   └── service
│   ├── dto
│   ├── port
│   │   ├── inbound
│   │   └── outbound
│   ├── configuration
│   ├── event
│   ├── exception
│   ├── mapper
│   ├── utils
│   └── test
├── feature-b
│   ├── adapter
│   ├── application
│   ├── domain
│   ├── dto
│   ├── port
│   ├── configuration
│   └── test
├── common (공통 모듈)
│   ├── security
│   ├── messaging
│   ├── exception
│   ├── utils
│   └── test
└── shared (공유 리소스)
    ├── api-clients
    ├── shared-entity
    ├── shared-dto
    └── event


구체적인 분리 전략

  1. Feature 간 통신

    • 동기 통신: REST API 또는 gRPC를 사용.

    • 비동기 통신: Kafka, RabbitMQ와 같은 메시지 브로커를 사용.

  2. Feature 내부 구조

    • 각 Feature는 완전한 헥사고날 아키텍처를 유지.

    • adapter, application, domain, port로 구성하여 독립성을 보장.

  3. 공통 코드 관리

    • 공통 코드는 common 디렉터리에서 관리.

    • 각 Feature가 필요에 따라 가져다 사용.

  4. 테스트 분리

    • 단위 테스트는 Feature 내에서 진행.

    • 통합 테스트는 Feature 간의 상호작용을 확인.

  5. 데이터베이스 분리

    • 가능한 경우 각 Feature가 별도의 데이터베이스를 관리(MSA의 원칙).

    • 동일한 데이터베이스를 사용해야 한다면, 데이터 접근은 Repository를 통해 제한.


MSA 최적화를 위한 추가 팁

  1. API Gateway

    • 외부 요청은 API Gateway를 통해 라우팅.

    • 각 Feature는 내부적으로 독립적으로 동작.

  2. Feature별 배포

    • 각 Feature는 독립적으로 빌드 및 배포 가능하도록 설계.

    • Docker, Kubernetes를 활용.

  3. 모니터링과 로깅

    • 각 Feature의 상태를 중앙에서 모니터링.

    • 로그는 통합된 시스템(예: ELK 스택)에서 관리.

  • No labels