chap00의 핵심은 여기서 가장 잘 드러난다

모놀리식의 장점은 개념 설명만으로는 잘 느껴지지 않는다.

하지만 주문 흐름을 보면 왜 이 구조가 처음에는 강력한지 곧바로 이해할 수 있다.

chap00에서 주문은 단순히 주문 테이블에 한 줄을 넣는 작업이 아니다.

주문을 만들려면 재고가 줄어들어야 하고, 주문 상품이 저장되어야 하고, 배송도 함께 생성되어야 한다.

그런데 이 모든 일이 하나의 애플리케이션 안에서 거의 한 번에 이어진다.

주문 생성은 어떻게 이어지는가

주문 생성 흐름을 큰 단계로만 보면 아래와 같다.

  1. 주문 엔티티를 만든다.
  2. 주문한 상품 수량만큼 재고를 줄인다.
  3. 주문 상품 목록을 저장한다.
  4. 배송 정보를 만든다.
  5. 주문 상태를 완료로 바꾼다.

독자가 여기서 봐야 할 핵심은 각 단계를 구현한 코드의 세세한 문법이 아니다.

중요한 것은 이 흐름이 모두 같은 애플리케이션 안의 서비스 협력으로 이어진다는 점이다.

즉, 주문 서비스는 필요할 때 상품 서비스와 배송 서비스를 네트워크 너머의 다른 시스템처럼 대하지 않는다.

그냥 같은 애플리케이션 안의 협력 대상으로 부른다.

이 점은 실제 코드에서도 바로 드러난다.

@Transactional
public OrderResponse createOrder(int userId, List<OrderRequest.OrderItemDTO> orderItems, String address) {
    Order createdOrder = orderRepository.save(Order.create(userId));
    int orderId = createdOrder.getId();

    for (OrderRequest.OrderItemDTO item : orderItems) {
        productService.decreaseQuantity(item.productId(), item.quantity(), item.price());
    }

    List<OrderItem> createdOrderItems = orderItems.stream()
            .map(item -> OrderItem.create(orderId, item.productId(), item.quantity(), item.price()))
            .toList();
    orderItemRepository.saveAll(createdOrderItems);

    deliveryService.createDelivery(orderId, address);
    createdOrder.complete();

    return OrderResponse.from(createdOrder, createdOrderItems);
}

이 코드 조각만 봐도 흐름이 비교적 단순하다는 사실이 드러난다.