Order Processing Workflow
A production-quality example demonstrating how functional patterns solve real business problems.
Overview
The Order Processing Workflow is a comprehensive e-commerce example that processes customer orders through multiple stages: validation, inventory reservation, payment processing, shipment creation, and notification. It showcases how Higher-Kinded-J patterns handle complexity without sacrificing readability.
┌─────────────────────────────────────────────────────────────────────────┐
│ ORDER PROCESSING PIPELINE │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ Request ──▶ Validate ──▶ Customer ──▶ Inventory ──▶ Discount │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ Address? Exists? In Stock? Valid Code? │
│ Postcode? Eligible? Reserved? Loyalty Tier? │
│ │
│ ──▶ Payment ──▶ Shipment ──▶ Notification ──▶ Result │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ Approved? Created? Sent? │
│ Funds? Carrier? (non-critical) │
│ │
└─────────────────────────────────────────────────────────────────────────┘
Key Patterns Demonstrated
Typed Error Hierarchies
Domain errors modelled as a sealed interface hierarchy for exhaustive pattern matching:
public sealed interface OrderError {
record ValidationError(String field, String message) implements OrderError {}
record CustomerNotFound(CustomerId id) implements OrderError {}
record InsufficientInventory(ProductId id, int requested, int available) implements OrderError {}
record PaymentDeclined(String reason) implements OrderError {}
record ShipmentFailed(String carrier, String reason) implements OrderError {}
}
ForPath Comprehensions
Clean, readable workflow composition with ForPath:
public EitherPath<OrderError, OrderResult> processOrder(OrderRequest request) {
return ForPath.forPath(validateRequest(request))
.bind(validated -> lookupCustomer(validated.customerId()))
.bind((validated, customer) -> reserveInventory(validated.lines()))
.bind((validated, customer, reservation) ->
applyDiscounts(validated, customer))
.bind((validated, customer, reservation, discount) ->
processPayment(customer, discount.finalAmount()))
.bind((validated, customer, reservation, discount, payment) ->
createShipment(validated, reservation))
.map((validated, customer, reservation, discount, payment, shipment) ->
new OrderResult(validated.orderId(), shipment, payment));
}
Resilience Patterns
Built-in retry policies and timeouts for external service calls:
private EitherPath<OrderError, PaymentConfirmation> processPaymentWithRetry(
Customer customer, Money amount) {
return Path.io(() -> paymentService.charge(customer, amount))
.retry(RetryPolicy.exponentialBackoff(3, Duration.ofMillis(100)))
.timeout(Duration.ofSeconds(5))
.mapError(e -> new PaymentDeclined(e.getMessage()));
}
Focus DSL Integration
Immutable state updates using generated lenses:
// Update nested order status
Order updated = OrderFocus.status().set(order, OrderStatus.CONFIRMED);
// Modify all line item quantities
Order adjusted = OrderFocus.lines()
.traverseEach()
.compose(OrderLineFocus.quantity())
.modify(order, qty -> qty + 1);
Source Files
| File | Description | Run Command |
|---|---|---|
| OrderWorkflowDemo.java | Main demo runner | ./gradlew :hkj-examples:run -PmainClass=org.higherkindedj.example.order.runner.OrderWorkflowDemo |
| EnhancedOrderWorkflowDemo.java | Demo with concurrency | ./gradlew :hkj-examples:run -PmainClass=org.higherkindedj.example.order.runner.EnhancedOrderWorkflowDemo |
| OrderWorkflow.java | Core workflow | View source |
| ConfigurableOrderWorkflow.java | Feature flags and resilience | View source |
| EnhancedOrderWorkflow.java | VTask concurrency patterns | View source |
Domain Model
| File | Description |
|---|---|
| OrderError.java | Sealed error hierarchy |
| OrderRequest.java | Input request model |
| ValidatedOrder.java | Post-validation model |
| OrderResult.java | Workflow result |
Services
| File | Description |
|---|---|
| CustomerService.java | Customer lookup |
| InventoryService.java | Stock reservation |
| PaymentService.java | Payment processing |
| ShippingService.java | Shipment creation |
Extended Workflows
| File | Description |
|---|---|
| PartialFulfilmentWorkflow.java | Handling partial inventory |
| SplitShipmentWorkflow.java | Multi-warehouse shipping |
| OrderCancellationWorkflow.java | Cancellation with rollback |
Project Structure
hkj-examples/src/main/java/org/higherkindedj/example/order/
├── config/
│ └── WorkflowConfig.java # Feature flags and configuration
├── context/
│ └── OrderContext.java # Execution context
├── error/
│ └── OrderError.java # Sealed error hierarchy
├── model/
│ ├── OrderRequest.java # Input models
│ ├── ValidatedOrder.java # Domain models
│ ├── OrderResult.java # Result types
│ └── value/ # Value objects (Money, OrderId, etc.)
├── resilience/
│ ├── Resilience.java # Retry utilities
│ └── RetryPolicy.java # Policy definitions
├── runner/
│ ├── OrderWorkflowDemo.java # Main runner
│ └── EnhancedOrderWorkflowDemo.java
├── service/
│ ├── CustomerService.java # Service interfaces
│ ├── InventoryService.java
│ └── impl/ # In-memory implementations
└── workflow/
├── OrderWorkflow.java # Core workflow
├── ConfigurableOrderWorkflow.java
├── EnhancedOrderWorkflow.java
└── FocusDSLExamples.java # Focus DSL usage
Related Documentation
- Order Walkthrough – Step-by-step guide to the workflow
- Effect Composition – Detailed pattern explanations
- Production Patterns – Feature flags, retries, and configuration
- Concurrency and Scale – VTask, Scope, and structured concurrency
Next: Draughts Game