
Introduction
In this article, I will give an overview of the microservices patterns Event Sourcing and Command Query Responsibility Segregation (CQRS) patterns. Then I will show how to apply these concepts on a Spring Web Application using Axon Framework. You can check the final code onGithub.
I recommend you to already have some basic concepts of Java and Spring Boot for better comprehension.
Event Sourcing
This pattern implies every application state change should be started by an event, which should be stored. For example, at an e-commerce site, after the user clicks a product to add to the cart, this action should send a JSON event containing the product id and quantity.
The final application state will then be defined by the sequence of previously processed events.
The main benefits of using Event Sourcing instead of maintaining only the last application state are:
Audit: you can search the stored events and verify exactly which events led to the next state.
Replay: if there's an error on event processing (ex.: database is down), you can just trigger the failed events again.
Replicate: you can publish the events on a message broker (ex.: Apache Kafka) and consume on another microservice.
CQRS
A pattern that proposes the separation of reading operations from writing or updating operations. This can be done in many ways, from just creating separate classes to using distinct databases.
The main benefit of CQRS is the logic division of code, making it clearer.
Demo Application Overview
The application will consist of a Spring Boot that simulates an e-commerce checkout platform. Through REST endpoints, you can add or edit a product containing attributes ofid
,name
andquantity
.
Following CQRS concepts, there will be separate modules for command and query:
Command Side: will contain the
POST
andPUT
endpoints, that will generate its respectivecommands
, which will be translated intoevents
. The events will be stored into a MongoDb database in a raw format, while also being processed to generate the final application state and stored in a Postgres database.Query Side: will contain the
GET
endpoint to fetch the latest snapshot of our e-commerce cart.
Axon Framework gives us a simple recipe on CQRS and Event Sourcing implementation, making it easy to understand the data flow.
Dependencies
spring-boot-starter
spring-boot-starter-web
spring-boot-starter-data-mongodb
spring-boot-starter-data-jpa
axon-spring-boot-starter
axon-mongo
postgresql
We will be using version 4.1.2 ofaxon-spring-boot-starter
, which requires a separateAxon Server running to start our Spring Boot Application. To simplify this tutorial, we won't make use of Axon Server, so we can remove its dependency by declaring onbuild.gradle
file:
compile('org.axonframework:axon-spring-boot-starter:4.1.2'){excludegroup:'org.axonframework',module:'axon-server-connector'}
Command module configuration
We will start by creating theCommand
module. If you're using IntelliJ, you can do it by clickingFile > New > Module
, selectGradle
, thenJava
. InArtfactId
typecommandside
thenFinish
. This step will create a folder calledcommandside
in the root folder of your application containing a singlebuild.gradle
file. Check its configurationhere on Github repository.
Next, you need to create the structure of a Spring Boot application insidecommandside
folder by creating a path internally containing your main packagesrc/main/java/com/example/project/command
. where it will be placed your@SpringBootApplication
annotated class and all other package related classes. Check the final resulthere.
Insidesrc/main/resources
, create anapplication.yml
file to place your Postgres configuration. You can follow my examplehere.
The most important step now is the configuration ofEventStorageEngine
of Axon, which will be MongoDb in our example. To do this, create aConfiguration
class like this:
@ConfigurationpublicclassAxonConfig{// The `MongoEventStorageEngine` stores each event in a separate MongoDB document@BeanpublicEventStorageEnginestorageEngine(MongoClientclient){returnMongoEventStorageEngine.builder().mongoTemplate(DefaultMongoTemplate.builder().mongoDatabase(client).build()).build();}}
Query
module doesn't require any special configuration. It will be a simple Spring Boot web application that fetches view models from the Postgres database.
Run your application now to check if everything works.
Conclusion
In this first part, we've discussed the basic concepts of CQRS and structured our demo application. In the next step, we will code theCommand
module.
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse