Skip to content

Latest commit

 

History

History
258 lines (178 loc) · 8.95 KB

File metadata and controls

258 lines (178 loc) · 8.95 KB

Design of MicroProfile E-commerce Application using Reactive Messaging

This document provides a service-by-service design for using Reactive Messaging in the MicroProfile e-Commerce application. It outlines the recommended channels, event payloads, and responsibilities for each microservice, while also recommending a hybrid architecture that combines synchronous REST calls with asynchronous event-driven communication.

Design goals

  • Keep each service responsible for its own data and lifecycle transitions.

  • Use events for long-running business workflow progression instead of tightly coupled HTTP chains.

  • Keep REST for reads, administration, direct client queries, and immediate request/response interactions.

  • Combine REST and Reactive Messaging in a practical hybrid architecture.

  • Start simple with in-memory wiring, then switch to Kafka for multi-service deployment.

A pure event-driven design is not required for every interaction. In this application, the most practical approach is a hybrid model:

  • Use REST with MicroProfile Rest Client for operations that need an immediate response, such as fetching data, validating requests, or initiating checkout.

  • Use Reactive Messaging for asynchronous workflow steps that span multiple services, such as payment authorization, inventory reservation, shipment updates, and status notifications.

Use REST for

  • shopping cart and checkout initiation

  • synchronous reads and lookups

  • administrative CRUD operations

  • validations where the caller needs an immediate result

Use Reactive Messaging for

  • order lifecycle events

  • payment success or failure notifications

  • inventory reservation outcomes

  • shipping progress updates

  • audit, monitoring, and user notifications

Channel Produced by Consumed by Purpose

order-created

Order Service

Payment Service

Publish a newly persisted order that is ready for payment.

payment-authorized

Payment Service

Inventory Service, Order Service

Notify that payment succeeded.

payment-failed

Payment Service

Order Service

Notify that payment was rejected or failed.

inventory-reserved

Inventory Service

Shipment Service, Order Service

Notify that stock has been reserved successfully.

inventory-rejected

Inventory Service

Order Service

Notify that stock could not be reserved.

shipment-created

Shipment Service

Order Service

Notify that shipment processing has started.

shipment-dispatched

Shipment Service

Order Service, User Service

Notify that the package has left the warehouse.

shipment-delivered

Shipment Service

Order Service, User Service

Notify that the order has been delivered.

order-status-events

Order Service

Shopping Cart Service, User Service, observability components

Publish normalized order state changes for downstream consumers.

Suggested event payload classes

Use small, explicit payload types rather than reusing full JPA-style entities everywhere.

  • OrderCreatedEvent

  • PaymentResultEvent

  • InventoryReservationEvent

  • ShipmentEvent

  • OrderStatusChangedEvent

Each event should include identifiers such as orderId, userId, timestamp, and only the fields needed by downstream services.

Service-by-service design

Shopping Cart Service

The Shopping Cart service remains the user-facing checkout initiator. Checkout begins synchronously through REST, and then transitions into an event-driven workflow once the order has been accepted.

Suggested bean classes:

  • CheckoutClient

    • Uses RestClient to call the Order Service synchronously at checkout time

  • OrderStatusListener

    • Consumes order-status-events to show current order progress in the UI

Recommended responsibility:

  • Keep cart calculation and cart management synchronous.

  • Use REST to submit the order when the user confirms checkout.

  • Rely on downstream events only after the order has been accepted and persisted.

Order Service

The Order service should remain the system of record for order lifecycle state.

Suggested bean classes:

  • OrderCreationHandler

    • Called by the existing REST-based checkout flow

    • Calls the existing OrderService.createOrder(…​)

    • Emits OrderCreatedEvent to order-created

  • OrderStatusEventHandler

    • Consumes payment-authorized, payment-failed, inventory-reserved, inventory-rejected, shipment-created, shipment-dispatched, and shipment-delivered

    • Calls the existing OrderService.updateOrderStatus(…​)

  • OrderStatusPublisher

    • Emits normalized updates to order-status-events

Recommended responsibility:

  • Persist the initial order.

  • Listen for downstream business outcomes.

  • Update status transitions such as CREATED, PAID, PROCESSING, SHIPPED, and DELIVERED.

Payment Service

The Payment service should react to newly created orders and publish payment outcomes.

Suggested bean classes:

  • PaymentRequestHandler

    • @Incoming("order-created")

    • Uses payment gateway logic from the current PaymentService

    • Emits to either payment-authorized or payment-failed

  • PaymentAuditLogger

    • Consumes payment-authorized and payment-failed for audit and telemetry

Recommended responsibility:

  • Own payment authorization and failure handling.

  • Avoid direct synchronous callbacks into Order where possible.

Inventory Service

The Inventory service should reserve or reject stock after payment authorization.

Suggested bean classes:

  • InventoryReservationHandler

    • @Incoming("payment-authorized")

    • Uses the existing InventoryService to validate products and update quantities

    • Emits inventory-reserved or inventory-rejected

  • LowStockPublisher

    • Emits optional low-stock notifications when quantity drops below a threshold

Recommended responsibility:

  • Keep inventory ownership local to the Inventory service.

  • Publish stock reservation outcomes instead of requiring the Order service to poll or chain REST calls.

Shipment Service

The Shipment service should start logistics only after inventory is successfully reserved.

Suggested bean classes:

  • ShipmentRequestHandler

    • @Incoming("inventory-reserved")

    • Creates a shipment record and emits shipment-created

  • ShipmentLifecyclePublisher

    • Emits shipment-dispatched and shipment-delivered

Recommended responsibility:

  • Replace parts of the current direct HTTP-based coordination with event-driven shipment updates.

  • Keep shipment lifecycle state local to the Shipment service.

User Service

The User service does not need to sit in the core order-processing path, but it can subscribe to status updates for communication and personalization.

Suggested bean classes:

  • UserNotificationHandler

    • @Incoming("order-status-events")

    • Sends order progress notifications such as paid, shipped, or delivered

Recommended responsibility:

  • Consume events for user-facing notifications rather than participating in transactional order workflow.

Catalog Service

The Catalog service can remain mostly REST-based for product browsing and product lookup.

Suggested bean classes:

  • ProductChangedPublisher (optional)

    • Emits product update events when price or availability metadata changes

  • InventoryProjectionHandler (optional)

    • Consumes low-stock or inventory-summary events if a denormalized read model is needed

Recommended responsibility:

  • Keep product reads synchronous and simple.

  • Add messaging only when product updates need to be broadcast to other services.

End-to-end workflow

  1. Shopping Cart initiates checkout using a synchronous REST call to the Order Service

  2. Order Service persists the order and emits order-created

  3. Payment Service consumes order-created and emits payment-authorized or payment-failed

  4. Inventory Service consumes payment-authorized and emits inventory-reserved or inventory-rejected

  5. Shipment Service consumes inventory-reserved and emits shipment-created, then shipment-dispatched, then shipment-delivered

  6. Order Service consumes all result events and emits normalized order-status-events

  7. User-facing and observability components subscribe to order-status-events

This approach gives the caller an immediate response at checkout time while still allowing the fulfillment workflow to proceed asynchronously across services.

Practical adoption plan

Step 1: Introduce payment messaging

  • Order Service publishes order-created

  • Payment Service consumes it and publishes payment-authorized

Step 2: Add inventory reservation

  • Inventory Service consumes payment-authorized

  • Publish inventory-reserved and inventory-rejected

Step 3: Add shipment lifecycle events

  • Shipment Service consumes inventory-reserved

  • Emit shipment lifecycle messages

Step 4: Publish normalized order state

  • Order Service becomes the single place that converts downstream outcomes into official order statuses