Help us measure site usage?

With your permission, we use self-hosted analytics to understand page usage. It is optional and does not affect the Service. Learn more.

JavaadvancedbackendAI generated

Event-Sourced Order Service

Build an order service in Spring Boot using event sourcing: instead of storing an order's current state and overwriting it, the service stores every change as an event (order placed, item added, paid, shipped, cancelled) in PostgreSQL, and the current state is rebuilt by replaying those events. This gives a complete audit trail of who changed what and when, and makes it possible to see an order as it was at any moment. Read-optimized views (projections) are kept up to date from the events and can be rebuilt from scratch at any time. Events are stored as JSON with Jackson. You'll learn event sourcing, aggregates and business rules, optimistic concurrency with event versions, projections, event schema changes, and testing with Spring Boot.

Estimate
~16h
Steps
7
Completed by
0
Proposed by
codeseed.app

Spring Boot · PostgreSQL · Jackson

Project roadmap

  1. 01

    Design the order events

    ~2.5h

    Write DESIGN.md: the order's events (OrderPlaced, ItemAdded, ItemRemoved, OrderPaid, OrderShipped and OrderCancelled) with their data, the rules (no changes after shipping, can't ship before payment, and cancellation only before shipping), the events table (id, order id, version, type, data as JSONB, metadata such as user and time, with a unique index on order id plus version), and the projections (order summaries, and daily sales). Done when: DESIGN.md covers events, rules and projections.

  2. 02

    Store events

    ~2.5h

    Create the table with Flyway. Write an EventStore that appends events for an order with the version it expects, failing with a concurrency error when another change got there first (caught from the unique index), and loads an order's events in order. Serialize events with Jackson using type information, so each is read back as the right class. Done when: appending and loading events works, and two simultaneous appends at the same version give one success and one conflict.

  3. 03

    Enforce the rules in an aggregate

    ~2.5h

    Write an Order class that rebuilds its state by applying events in order, and command methods (place, add item, pay, ship and cancel) that check the rules and return new events without saving anything. A command service loads the order, runs the command, and appends the new events with the expected version, retrying once on a conflict. Done when: valid commands produce events, and invalid ones are refused with clear messages.

  4. 04

    Build projections

    ~2.5h

    Build projection tables (order summaries with status and total, and daily sales) and a projector that processes events in order, remembering the last event it handled and updating the tables idempotently. Add an admin endpoint that rebuilds a projection from scratch. Done when: projections match a full replay of the events, including after a rebuild.

  5. 05

    Expose the API and audit trail

    ~2h

    Add REST endpoints for the commands (returning 409 on concurrency conflicts and 422 on rule violations), GET /orders (from the projection), GET /orders/{id}/history (the events with who and when), and GET /orders/{id}?at=TIME (the order rebuilt from events up to a moment). Done when: every endpoint works, and history explains every change.

  6. 06

    Handle event changes

    ~1.5h

    Change the shape of one event (for example adding a currency to OrderPaid) and handle old stored events by upgrading them when they're read (upcasting), without changing the stored data. Add snapshots for orders with many events if needed. Done when: old and new versions of the event are both read correctly.

  7. 07

    Test it

    ~2.5h

    Write tests: aggregate rules as plain unit tests (given these events, when this command, then these events or this error), event store concurrency with Testcontainers PostgreSQL, projection rebuilds matching live updates, point-in-time reads, and upcasting old events. Done when: all tests pass.

Ready to build this?

Get a GitHub repo and start building. Your AI reviewer checks each step as you go.

~16h · 7 steps

Tech stack

Spring BootPostgreSQLJackson