A comprehensive reference implementation of Command Query Responsibility Segregation (CQRS) and Event Sourcing patterns using Spring Boot 3 and Java 21.
This project demonstrates how to implement CQRS and Event Sourcing in a modern Spring Boot application. It includes:
- Domain-Driven Design with aggregates and domain events
- Event Sourcing for persisting state changes as events
- CQRS with separate command and query models
- Event-driven architecture with event handlers for projections
- REST API for commands and queries
- Complete order management example domain
-
Domain Layer
AggregateRoot: Base class for aggregates with event sourcing capabilitiesDomainEvent: Base class for all domain eventsOrder: Example aggregate implementing business logic
-
Command Side (Write Model)
- Commands:
CreateOrderCommand,AddOrderItemCommand, etc. - Command Handlers: Process commands and interact with aggregates
- Event Store: Persists domain events
- Commands:
-
Query Side (Read Model)
- Projections: Denormalized views optimized for queries
- Event Handlers: Update projections when events occur
- Query Services: Provide read access to projections
-
Infrastructure
EventStore: Interface for event persistenceJpaEventStore: JPA implementation of event storeAggregateRepository: Repository for loading/saving aggregates
- Java 21
- Maven 3.8+
mvn spring-boot:runThe application will start on http://localhost:8080
Access the H2 console at http://localhost:8080/h2-console
- JDBC URL:
jdbc:h2:mem:eventstore - Username:
sa - Password: (empty)
POST /api/orders
Content-Type: application/json
{
"customerName": "John Doe"
}POST /api/orders/{orderId}/items
Content-Type: application/json
{
"productName": "Laptop",
"quantity": 2,
"unitPrice": 999.99
}POST /api/orders/{orderId}/confirmPOST /api/orders/{orderId}/cancelGET /api/orders/{orderId}GET /api/ordersGET /api/orders?customerName=John&status=CONFIRMED- Create an order:
curl -X POST http://localhost:8080/api/orders \
-H "Content-Type: application/json" \
-d '{"customerName": "John Doe"}'- Add items to the order:
curl -X POST http://localhost:8080/api/orders/{orderId}/items \
-H "Content-Type: application/json" \
-d '{"productName": "Laptop", "quantity": 1, "unitPrice": 1200.00}'- Confirm the order:
curl -X POST http://localhost:8080/api/orders/{orderId}/confirm- Query the order:
curl http://localhost:8080/api/orders/{orderId}Run the tests with:
mvn testThis project is licensed under the Apache 2.0 License - see the LICENSE file for details.