MSA 구조 내에서 메시지 큐 폴더 위치에 대해 피드백 받았다.
Application 레벨에 넣었지만, Infrastructure 레벨에 넣는게 맞다고 하셨다.
Infrastructure 레벨은 애플리케이션의 핵심 비즈니스 로직을 지원하는 기술적인 부분을 담당한다.
여기에는 DB, MessageQueue, 외부 API 통신 등 외부 시스템과의 상호작용을 처리하는 코드가 포함되는 영역이기 때문이다.
또, Adaptor 폴더에 넣으라고 피드백 주셨다.
Adaptor 패턴은 외부 시스템과의 인터페이스를 추상화하여 애플리케이션의 핵심 로직이 외부 시스템에 직접적으로 의존하지 않도록 한다.
그래서 외부 시스템 변경이 애플리케이션에 미치는 영향을 최소화하고, 코드의 유연성과 유지보수성을 높이는 데 도움이 된다.
service -> infrastructure 레벨로 폴더 옮기기
adaptor 폴더 내 Listener 파일 넣기
OrderQueueListener 파일명을 변경하여 행위를 명확히 표현하기
OrderQueueListener 파일 내에서는 메시지 큐 수신 + 비즈니스 로직이 들어있다.
하지만 피드백 주신 내용 중, 큐 시스템 변경 또는 로직 변경했을 때 각 부분만 수정하면 되므로 전체 시스템에 미치는 영향을 최소화할 수 있다고 말씀해주셨다.
또 다른 영향이 있는지 알아보았는데, 관심사 분리 부분이 있었다.
큐 수신은 기술적인 측면이고, 비즈니스 로직은 도메인에 특화된 측면이다.
이 둘을 분리함으로 각 부분의 책임이 명확해지며, 코드의 가독성 + 유지보수성이 향상될 수 있다고 한다.
@Transactional
@RabbitListener(queues = "${message.queue.order}")
public void queueOrderListen(DeliveryCreationResponseDto deliveryCreationResponseDto) {
Order order = orderHelper.getByOrderId(deliveryCreationResponseDto.orderId());
OrderDetail orderDetail = orderHelper.getByOrderDetailId(order, deliveryCreationResponseDto.orderDetailId());
orderDetail.updateDelivery(deliveryCreationResponseDto.deliveryId());
orderRepository.save(order);
String[] stopoverNames = deliveryCreationResponseDto.deliveryStopoverNames().split(",");
String message = makeMessage(order, orderDetail, deliveryCreationResponseDto, stopoverNames);
rabbitTemplate.convertAndSend(queueSlack, new SlackMessageDto(order.getRequesterUserId(), message));
}
@Transactional
@RabbitListener(queues = "${message.queue.order}")
public void queueOrderListen(DeliveryCreationResponseDto deliveryCreationResponseDto) {
orderService.processOrderQueue(deliveryCreationResponseDto);
}
public void processOrderQueue(DeliveryCreationResponseDto deliveryCreationResponseDto) {
Order order = orderHelper.getByOrderId(deliveryCreationResponseDto.orderId());
OrderDetail orderDetail = orderHelper.getByOrderDetailId(order, deliveryCreationResponseDto.orderDetailId());
orderDetail.updateDelivery(deliveryCreationResponseDto.deliveryId());
orderRepository.save(order);
String[] stopoverNames = deliveryCreationResponseDto.deliveryStopoverNames().split(",");
String message = makeMessage(order, orderDetail, deliveryCreationResponseDto, stopoverNames);
rabbitTemplate.convertAndSend(queueSlack, new SlackMessageDto(order.getRequesterUserId(), message));
}
Infrastructure 레벨은 애플리케이션의 핵심 비즈니스 로직을 지원하는 기술적인 부분을 담당한다.
여기에는 DB, MessageQueue, 외부 API 통신 등 외부 시스템과의 상호작용을 처리하는 코드가 포함되어야한다.
또, Adaptor 폴더에 넣어야하는데, 외부 시스템 변경이 애플리케이션에 미치는 영향을 최소화하고, 코드의 유연성과 유지보수성을 높이는 데 도움이 되기 때문이다.
메시지 큐 수신 파일에서 큐 수신과 비즈니스 로직을 분리하는 것은 소프트웨어 아키텍처의 핵심 원칙인 "관심사의 분리" 를 따르는 것이다.
이를 통해 코드의 유지보수성, 테스트 용이성, 시스템 확장성 및 안정성을 향상시키고, 메시지 처리의 유연성을 확보할 수 있다.