Example of Event Sourcing Pattern with CQRS implemented in Spring Boot with EventStoreDB.
Read model stored in MongoDB.
Used Docker to containerize environment.
Exposes REST endpoints to create, update, and delete citizens.
The endpoints send EventStoreDB events.
To avoid eventual consistency, currentRevision
validation was introduced (this obviously depends on the project use-case).
Sometimes it happens that the connection to EventStoreDB is broken, hence a very simple retry mechanism was implemented.
Consumes EventStoreDB events and updated customers' read models stored in MongoDB.
It is possible to create more services similar to this one, which will handle the data differently, store it in different databases, etc.
It is also possible not to have a read model service at all. If there are not many events per aggregate, it is possible to build a model based on all occurred events from EventStoreDB every time an endpoint is requested.
Exposes REST endpoints to query citizens. Returns a MongoDB Citizen read model data when the read model endpoint is requested, and all the events stored in EventStoreDB when the audit endpoint is requested.
- Make sure you have
Docker
installed
Docker installation - Install
Docker Compose
to run the importer locally
Docker Compose installation
# Build and run services
$ docker-compose up --build
# Create a citizen
$ curl --location --request POST 'localhost:8081/citizens' \
--header 'Content-Type: application/json' \
--data-raw '{
"citizenId": "4jf74jfi84jmf",
"firstName": "John",
"lastName": "Smith",
"address": "Mount Pleasant Gardens 33, London"
}'
# Update the citizen
$ curl --location --request PUT 'localhost:8081/citizens' \
--header 'Content-Type: application/json' \
--data-raw '{
"citizenId": "4jf74jfi84jmf",
"firstName": "John",
"lastName": "Smith",
"address": "Moorfield Alley 15, London"
}'
# Delete the citizen
$ curl --location --request DELETE 'localhost:8081/citizens?citizenId=4jf74jfi84jmf'
# Get the citizen's read model
$ curl --location --request GET 'localhost:8082/citizens?citizenId=4jf74jfi84jmf'
# Get the citizen's audit
$ curl --location --request GET 'localhost:8082/audit?citizenId=4jf74jfi84jmf'