CQRS and Event Sourcing with Axon Framework
7 minute read
After a few years of working with Axon Framework, it is time to step back, zoom out and do a retrospective.
We have successfully implemented Axon Framework on several projects and gained a huge experience.
It was challenging, especially in the beginning, because we had to change the programming paradigm, study about the new architecture and change the way we develop our applications. Luckily for us, we enjoy experimenting with new technologies, and we employ many developers who are eager to tackle new challenges.
How did we start?
Some of our senior engineers started talking about CQRS and Event Sourcing and the possibility of implementing it in a production environment because frameworks that could ease implementation started to show up on the horizon. We are a company that relies heavily on Spring Framework, and we were pleased to hear the official announcement of Spring Boot and Axon integration. That was a green light for us to start using Axon Framework in our development. We received an additional boost from the author of Axon Framework, Allard Buijze, who came to Zagreb and shared huge knowledge in this domain with us.
What is CQRS?
Four letters stand for Command Query Responsibility Segregation. It is an architecture that has one model for saving data and another model for querying data. The purpose of model separation is the query side’s need for viewing and organizing data structure differently. Maybe collapsing multiple records into one, using a different ER model, using a non-relational database, or perhaps scaling query side application because of a heavy load. It is a very interesting topic and you can read more on the following link.
What is Event Sourcing? Is it required with CQRS?
Event Sourcing means saving all changes in your application as a series of Events. So that we, in one place, have all history of changes, and we can reconstruct events from the past. You probably used something similar in your applications, using audit tables or saving all requests that came to your application, but you didn’t rely on those data as Event Store. Event Sourcing is not required in combination with CQRS but it fits very nicely. More information about this topic is available on this link.
What is the Axon Framework?
Axon Framework in combination with Spring Boot makes it easy to implement two patterns that we just discussed, CQRS and Event Sourcing, especially in event-driven architecture. It uses terminology from Domain Driven Design which you should be familiar with before you start using Axon. The main building blocks are Aggregate, Repositories, Command, Event, Event Store, which are all concepts from Domain Driven Design. It provides out-of-the-box support to transfer Events to and from an AMQP message broker, such as Rabbit MQ.
Things to be aware of
Event Sourcing and CQRS are great concepts but not all use cases call for them. Simple applications that don’t care about events and have no requirements on audit would be better off with traditional CRUD-like architecture. You will need experienced architects with good knowledge of the domain to decide which architecture to use.
If you opt for Event Sourcing and CQRS, be prepared for a certaing learning curve. Benefits that Event Sourcing and CQRS deliver come at the expense of programming paradigm shift. Get your engineers ready for it.
You have to think differently about transactions because classic ACID transactions are not possible in all situations. In Axon Framework you can use Sagas, a solution found in microservice event-driven architecture. With Sagas, you are not doing classic rollback if something goes wrong. Instead, you initiate compensating action that will revert everything in the correct state. With that, you get Eventual Consistency.
You have to accept the fact that you can’t modify Events in the database. Regardless of architecture that is not the correct way to fix things.
Situations where Axon shines
The configuration is very easy, very minimal and thus not polluting your code. Most of the things are done through annotations and because of that, every Java/Spring developer will probably feel very comfortable configuring Axon. On that track, it is very easy to choose between saving current Aggregate state through standard JPA Repositories or to save a series of events using event sourcing repositories.
The scenario in which Axon truly shines is when there are several interested parties for Events and everyone wants different projection of Event. Imagine that different parties were Splunk, MongoDB, Camunda, and Oracle. In Axon, you implement this by creating a separate tracking or subscribing processor for each consumer. The processor will react to the event, populate projection, and send data to the consumer.
Another very practical feature is resetting index in case you want replay events for some specific period of time. You can replay events for all consumers or a specific consumer. The common use case for the replay is a loss of data, testing purposes, and creating data set for DWH.
You have to think in advance about your Bounded Context, about your Aggregates, Commands, Events and other patterns from Domain Driven Design which is a good thing if you don’t want end up with Anemic Domain Model. The best technique to discover those things is through Event Storming workshop where developers, architects and domain experts explore complex business domain. The result is a clear and more robust architecture that is easier to communicate with colleagues. It is always very important to have domain experts when designing application, but in this kind of architecture it is crucial. Poorly designed domain can be very expensive to fix later in development.
In the end, Axon is now a mature project, with stable versions that are up to date with the newest Spring Boot versions. It has a relatively big community and a decent amount of good resources on the internet, which we all know, is very important for developers.
QED2023 is very special as we will gather for the 15th time!
That’s why this year’s topic will be VALUE!