Appearance
E-Commerce Reference Application
The example/e-commerce application is an advanced reference architecture demonstrating how to build complex, multi-domain enterprise systems.
Unlike the minimal Bank Account or Todo examples, this application showcases advanced Domain-Driven Design (DDD) patterns. It proves how flux enforces strict boundaries while allowing asynchronous cross-domain communication.
The Walkthrough: Project In-and-Outs
The application is cleanly divided into Bounded Contexts (domains) following the flux standard project layout. Let's trace how an order flows through this ecosystem.
1. The Catalog Domain (internal/catalog/)
The catalog domain is entirely responsible for products and pricing. It knows absolutely nothing about customers or sales.
- Aggregates:
- The
Productaggregate handles inventory and naming. - The
Pricingaggregate handles price history. We separated these because pricing rules often change independently of core product data, minimizing lock contention.
- The
- The Projection (Read Model):
- Look at
internal/catalog/projections/productview/projector.go. - This is a Cross-Aggregate Denormalizer. It listens to both
ProductCreatedandPricingSetevents. When the frontend asks for product information, it queries this unified projection instantly without needing to perform slow SQL joins across different aggregate streams!
- Look at
2. The Identity Domain (internal/identity/)
A simulated IAM (Identity and Access Management) domain. It provides the flux.Actor context. When a command is dispatched, the Identity domain ensures the traceability of who performed the action.
3. The Sales Domain (internal/sales/)
The sales domain handles the shopping cart and checkout process.
- Aggregates:
Customer: Manages the address book and profile.Order: Manages the lifecycle of a purchase.
- The Flow:
- When a user clicks "Checkout", a
salescmd.PlaceOrdercommand is dispatched to theOrderaggregate. - The
Orderaggregate validates the input and records asalesevents.OrderPlacedevent. - Crucial Concept: The
Orderaggregate does not process the credit card! It simply states that the order was placed and waits.
- When a user clicks "Checkout", a
4. The Global Workflow (internal/workflows/payment/)
How does the order actually get paid? This requires cross-domain coordination, which is the job of a Saga / Process Manager.
- Look at
internal/workflows/payment/workflow.go. - This workflow listens to the global
flux.EventBusfor thesalesevents.OrderPlacedevent. - When it intercepts an order, it tracks its own state in a
WorkflowStore. - It attempts to process the payment (simulated).
- Dispatching Back: If the payment succeeds, the workflow uses the
flux.CommandBusto dispatch asalescmd.PayOrdercommand back to the Sales domain. If it fails or times out, it dispatchessalescmd.CancelOrder.
This perfectly illustrates Choreography vs Orchestration. The Aggregates are purely reactive and ignorant of the outside world, while the Workflow orchestrates the complex multi-step process.
Running the Example
This reference application does not have a frontend UI. It is designed as an executable integration test suite to demonstrate the framework's behavior programmatically.
bash
cd example/e-commerce
go test -v -race ./...The Integration Test
Open integration_test.go at the root of the e-commerce folder. This test wires the entire distributed system together in-memory.
It simulates a complete end-to-end user journey:
- Creating a product and setting its price.
- Registering a customer and adding a shipping address.
- Placing an order with line items.
- Simulating the payment workflow successfully completing the order.
- Verifying the final denormalized state in the Catalog Projection.
It proves that the entire CQRS architecture functions perfectly in a heavily tested, decoupled environment.
