This project demonstrates a minimal implementation of Command Query Responsibility Segregation (CQRS) using Java, Helidon MP, and MongoDB via Jakarta NoSQL. Instead of focusing on infrastructure or completeness, the goal is to highlight the core idea behind CQRS: separating how the system processes commands (writes) from how it serves queries (reads). Through a simple card authorization scenario, you can observe how a command produces a decision and how that decision is later reflected in a query model, making the distinction between intent, state change, and representation explicit.
To run this project, you will need the following:
-
Java 21
-
Maven 3.9+
-
MongoDB (choose one option)
Option 1: MongoDB Atlas (Cloud)
-
A MongoDB Atlas account
-
A running cluster
-
Connection string configured in the application
Option 2: Local MongoDB (Docker)
docker run -d --name mongodb -p 27017:27017 mongo:latestmvn package
java -jar target/helidon-mongodb-events.jarcurl -X POST http://localhost:8080/cards/{cardId}/authorize \
-H "Content-Type: application/json" \
-d '{
"amount": 200
}'sequenceDiagram
participant Client
participant CommandResource
participant CommandHandler
participant Card
participant OperationResult
participant Projection
participant QueryResource
Client->>CommandResource: POST /cards/{id}/authorize
CommandResource->>CommandHandler: AuthorizeCardCommand
CommandHandler->>Card: load & validate
Card-->>CommandHandler: canAuthorize?
alt Approved
CommandHandler->>Card: debit(amount)
CommandHandler->>OperationResult: create APPROVED
CommandHandler->>Projection: update TransactionView
else Declined
CommandHandler->>OperationResult: create DECLINED
end
CommandHandler-->>CommandResource: OperationResult
CommandResource-->>Client: 200 OK (OperationResult)
Client->>QueryResource: GET /cards/{id}/transactions
QueryResource-->>Client: TransactionView[]