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.
-
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.
-
shopping cart and checkout initiation
-
synchronous reads and lookups
-
administrative CRUD operations
-
validations where the caller needs an immediate result
| Channel | Produced by | Consumed by | Purpose |
|---|---|---|---|
|
Order Service |
Payment Service |
Publish a newly persisted order that is ready for payment. |
|
Payment Service |
Inventory Service, Order Service |
Notify that payment succeeded. |
|
Payment Service |
Order Service |
Notify that payment was rejected or failed. |
|
Inventory Service |
Shipment Service, Order Service |
Notify that stock has been reserved successfully. |
|
Inventory Service |
Order Service |
Notify that stock could not be reserved. |
|
Shipment Service |
Order Service |
Notify that shipment processing has started. |
|
Shipment Service |
Order Service, User Service |
Notify that the package has left the warehouse. |
|
Shipment Service |
Order Service, User Service |
Notify that the order has been delivered. |
|
Order Service |
Shopping Cart Service, User Service, observability components |
Publish normalized order state changes for downstream consumers. |
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.
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
RestClientto call the Order Service synchronously at checkout time
-
-
OrderStatusListener-
Consumes
order-status-eventsto 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.
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
OrderCreatedEventtoorder-created
-
-
OrderStatusEventHandler-
Consumes
payment-authorized,payment-failed,inventory-reserved,inventory-rejected,shipment-created,shipment-dispatched, andshipment-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, andDELIVERED.
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-authorizedorpayment-failed
-
-
PaymentAuditLogger-
Consumes
payment-authorizedandpayment-failedfor audit and telemetry
-
Recommended responsibility:
-
Own payment authorization and failure handling.
-
Avoid direct synchronous callbacks into Order where possible.
The Inventory service should reserve or reject stock after payment authorization.
Suggested bean classes:
-
InventoryReservationHandler-
@Incoming("payment-authorized") -
Uses the existing
InventoryServiceto validate products and update quantities -
Emits
inventory-reservedorinventory-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.
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-dispatchedandshipment-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.
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.
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.
-
Shopping Cart initiates checkout using a synchronous REST call to the Order Service
-
Order Service persists the order and emits
order-created -
Payment Service consumes
order-createdand emitspayment-authorizedorpayment-failed -
Inventory Service consumes
payment-authorizedand emitsinventory-reservedorinventory-rejected -
Shipment Service consumes
inventory-reservedand emitsshipment-created, thenshipment-dispatched, thenshipment-delivered -
Order Service consumes all result events and emits normalized
order-status-events -
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.
-
Order Service publishes
order-created -
Payment Service consumes it and publishes
payment-authorized
-
Inventory Service consumes
payment-authorized -
Publish
inventory-reservedandinventory-rejected
-
Shipment Service consumes
inventory-reserved -
Emit shipment lifecycle messages