반응형
1. 강의에서 사용하는 아키텍처는?
: 레이어드 아키텍처와 DDD, EDA, 클린아키텍처(일부)를 종합하여 설계
2. 새로운 Architecture 를 적용한 배경
- 로직의 중심인 Domain 을 보호하고, 외부 시스템도 쉽게 변경할 수 있는 구조로 설계
- Facade 패턴을 이용, 프로젝트 초기 usecase 로 역할 수행하며, 도메인 레이어의 순환참조를 방지
- EDA 를 적절히 활용하여 Fat service 화를 방지 (도메인 별 트랜젝션 관리필요)
프로젝트 초기에는 facade 로 usecase 의 흐름을 관리하다 커지면 EDA 기반으로 흐름을 관리하여 도메인의 느슨한 결합 추구
3. 패키지 아키텍처 구조 및 Layer 설명
presentation
├── api
│ ├── controller // REST/gRPC 등 외부 요청 진입점
│ └── dto // Controller용 DTO (Request/Response)
└── event
│ └── consumer // Kafka, RabbitMQ 등 이벤트 수신 처리
└── scheduler
└── XXXscheduler // scheduler 이벤트 발생
Application //복잡한 도메인의 흐름제어가 필요한 경우 사용
├── facade //service flow 제어(단순 CRUD에선 생략)
domain
├── service // 도메인 서비스 (비즈니스 규칙)
├── repository interface // interface
├── entity // 도메인 모델 / Entity
└── domain dto // 도메인용 DTO
infrastructure
├── repository
│ ├── jpaRepository // JPA Repository 인터페이스
│ └── repository implementation // Repository 구현체
│ └── jpa entity // jpa entity
├── api client // 외부 API 호출 Adapter (feign 등)
└── producer
└── event // 이벤트 발행 구현체
| Layer | |
| Presentation | - 외부 요청을 받음. Controller에서 DTO 변환 후 service 호출 - 이벤트 Consumer 처리 - 스케줄러 이벤트 발생 |
| Application | - 도메인 순환참조를 방지하기 위해 facade 레이어를 위치하는 곳 - 프로젝트 초기에 usecase의 흐름을 관리 |
| Domain | - 핵심 비즈니스 로직 - 도메인 서비스/Entity/도메인 DTO - Repository Interface를 통해 외부 접근 |
| Infrastructure | - 외부 기술 구현체 - DB CRUD - API, 메시징을 Adapter 패턴으로 구현 - 도메인 인터페이스를 구현. |
1. Domain은 Infrastructure를 몰라야 함
2. Controller/Consumer/scheduler는 Application Layer 역할 없이 Presentation → Domain 호출 가능
3. 언제든 소스는 변경될 수 있음
: 하지만 변경되더라도 최소 코드만 변경하며, 핵심 비지니스 로직이 들어있는 도메인 서비스 단을 최대한 보호
4. 예제소스
1) Controller
@RestController
@RequestMapping("/orders")
class OrderController(private val orderService: OrderService) {
@PostMapping
fun createOrder(@RequestBody request: OrderRequest): OrderResponse {
val order = orderService.createOrder(
userId = request.userId,
items = request.items,
totalAmount = request.totalAmount
)
return OrderResponse(orderId = order.id!!, userId = order.userId, totalAmount = order.totalAmount)
}
@GetMapping("/{id}")
fun getOrder(@PathVariable id: Long): OrderResponse? {
val order = orderService.getOrder(id) ?: return null
return OrderResponse(orderId = order.id!!, userId = order.userId, totalAmount = order.totalAmount)
}
}
2) Domain Service
@Service
class OrderService(private val orderRepository: OrderRepository) {
fun createOrder(userId: Long, items: List<String>, totalAmount: Int): Order {
require(totalAmount > 0) { "총 금액은 0 이상이어야 합니다." }
val order = Order(userId = userId, items = items, totalAmount = totalAmount)
return orderRepository.save(order)
}
fun getOrder(id: Long): Order? = orderRepository.findById(id)
}
3) Domain Repository
interface OrderRepository {
fun save(order: Order): Order
fun findById(id: Long): Order?
}
4) Domain Entity
data class User(
val id: Long? = null,
val email: String,
val name: String,
val isActive: Boolean = true
) {
fun deactivate() = this.copy(isActive = false)
fun activate() = this.copy(isActive = true)
}
5) Repository Implementation
@Repository
class OrderRepositoryImpl(private val jpa: SpringDataOrderJpa) : OrderRepository {
override fun save(order: Order): Order {
val entity = OrderEntity.fromDomain(order)
return jpa.save(entity).toDomain()
}
override fun findById(id: Long): Order? =
jpa.findById(id).orElse(null)?.toDomain()
}
6) Consumer
@Component
class OrderEventConsumer {
fun handleOrderCreatedEvent(event: String) {
//서비스 레이어 호출
}
}
7) Producer
@Component
class OrderEventProducer {
fun publishOrderCreated(order: Order) {
}
}
8) Scheduler
@Component
class OrderScheduler() {
@Scheduled(fixedRate = 60000)
fun generateOrderEvent() {
//비지니스 로직이 담긴 서비스 메쏘드 호출
}
}
4. 장점 요약
"도메인 중심 설계"
- Domain Service가 핵심 로직만 담당, Infrastructure 몰라서 독립성 확보
"Presentation에서 Domain 직접 호출도 가능하도 application 에서 조율도 가능"
- 초기 빠른 개발에 유리
"서비스 확장 시 서비스 결합도 감소 가능"
- 점진적 확장 가능(Facade → EDA로 자연스러운 진화)
- Event 기반 통신으로 Publisher/Consumer 분리
"유연한 확장성"
- 새로운 이벤트 리스너나 Adapter 추가 용이
"테스트 용이성"
: Domain Service 단위 테스트 가능, 외부 의존은 Mock 처리
"읽기/유지보수 편리"
- 각 레이어가 명확하게 역할 구분반응형
'Kotlin Spring > Kotlin Spring 강의 내용' 카테고리의 다른 글
| 8) 테스트 코드 작성 (1)테스트 코드란? (0) | 2025.09.20 |
|---|---|
| 7) 주요 기능 개발(Back-end) (0) | 2025.09.02 |
| 6) 개발 architecture (4) EDA(Event-Driven Architecture) 패턴 (1) | 2025.08.31 |
| 6) 개발 architecture (3) 클린 아키텍처(Clean Architecture) (2) | 2025.08.31 |
| 6) 개발 architecture (2) 헥사고날 아키텍처(Hexagonal Architecture) (0) | 2025.08.31 |