event-driven commerce

EventDrivenStore

A general commerce base for an event-driven system, split across independent bounded contexts and service-owned databases.

Java.NETNode.jsKafkaMySQLMSSQL
Open repository

Order Transaction Flow

Gateway, service discovery, domain services, and event-driven outcomes.

Decoupled Resilient Scalable

Service Architecture

Client requests, discovery, domain services, and local data.

HTTPS requestfetch registered servicesservice registrationClientmakes an orderSpring Cloud GatewayAPI gateway / routerEureka Serverservice discoveryDomain Serviceseach service owns its dataOrder ServiceJava / Spring BootBilling ServiceNode.jsInventory Service.NETOrders DBMySQLBilling DBMariaDBInventory DBMSSQL

Event-Driven Order Lifecycle

From order creation to final state, orchestrated by events.

Kafka Event Backboneevent streaming platformOrderCreatedeventOrder.status =CREATEDReservation failedinventory eventInventoryReservedeventOrder.status =INVENTORY_REJECTEDOrder.status =INVENTORY_RESERVEDPaymentFailedeventPaymentAuthorizedeventOrder Cancelledfinal stateOrder.status =PAID

Key events

OrderCreatedInventoryReservedInventoryReservationFailedPaymentAuthorizedPaymentFailed

Legend

Synchronous request Asynchronous event State transition Order state Domain event

Design principles

  • Events over direct service calls
  • Independent, loosely coupled services
  • Service-owned databases
  • Observable retries and outcomes
Build resilient systems. Events turn transactions into progress.

Commerce flows where ownership is explicit.

Orders, inventory, and billing live as separate services; Kafka carries domain events while each service protects its own state. The repository deliberately uses different runtimes where they fit: Java and Spring Boot with MySQL for orders, .NET and C# with MSSQL for inventory, and Node.js with MariaDB for billing.

The useful part is the sequence, not just the ingredients.

  1. 01

    A client request enters through the gateway.

  2. 02

    The order service commits its local transaction.

  3. 03

    Kafka carries the resulting domain event.

  4. 04

    Inventory and billing react within their own boundaries.

  5. 05

    The workflow reaches success or publishes a compensating outcome.

Patterns that keep the system understandable as it grows.

01

Bounded contexts

Orders, inventory, and billing own separate responsibilities, data, and failure boundaries instead of sharing one application state.

02

Events over direct calls

Services publish facts to Kafka and consume only the events they need, keeping dependencies explicit and reducing synchronous coupling.

03

Saga choreography

Reservation and payment outcomes move the order forward. When a step fails, a compensating state can release or cancel earlier work.

04

Outbox and idempotency

The outbox pattern protects the handoff between a local database commit and event publication, while idempotent consumers tolerate retries.

Where this foundation could connect next.

Temporal

A natural next layer for workflows that become long-lived, need visible retries, or require durable timers beyond local event choreography.

Kubernetes + KEDA

A deployment path for independent services, with consumer scaling driven by Kafka lag instead of only CPU or memory.

Debezium + Schema Registry

Change-data capture and governed event contracts can make publication more resilient as services and teams multiply.

OpenTelemetry

Trace one order across the gateway, services, Kafka, and databases so the architecture stays explainable under failure.

This is the systems substrate behind a Gastrotech Pioneer: the same event-driven instincts can support orders, inventory, fulfillment, and payments without making the product feel like one giant application.