Implementing Event Sourcing Using Axon and Spring Boot - Part 1
We introduce the topic of event sourcing and why it can be powerful when used to develop microservices. Plus, we introduce the project we'll be working on in this series.
Join the DZone community and get the full member experience.Join For Free
In a previous post, we explored various data management patterns for microservices. One of the patterns we discussed was Event Sourcing. In this post, we will take the first step towards implementing Event Sourcing using Axon and Spring Boot.
So here's our plan of action:
- In Part 1, we will look at the concept behind Event Sourcing and discuss how we will implement it.
- Then, in Part 2, we will implement Event Sourcing using Axon and Spring Boot.
- Finally, in Part 3, we will finish our implementation and see Event Sourcing in action by testing our application.
So let's start with the first question.
What Is Event Sourcing?
The concept behind event sourcing is that every change to the state of the application should be captured. In other words, every action performed on an application entity should be persisted. Then, we can query those events. We can also use the list of events to reconstruct the current state of the object.
Let's look at a simple example to understand the concept. Assume that we have an accounting application. This application's job is to keep track of all the transactions occurring on an account. In other words, the account is an aggregate in this application.
Now, let's assume the following transactions occur on a particular account:
- Creation of the account with an initial balance of $100 USD.
- Account set to ACTIVE status.
- A friend paid some money back for sharing a meal. Deposit of $55 USD in the account.
- You bought ice cream for your significant other. Withdrawal of $20 USD.
- Your significant other didn't like the ice cream and so you had to buy another one. Withdrawal of $50 USD.
- You forgot to pay the rent. Your landlord imposed a penalty. Withdrawal of $100 USD.
- Account set to HOLD status because of a negative balance.
- Deposit $100 USD to the account. Breath a sigh of relief.
- Account set to ACTIVE status.
Pretty tough day, huh! But that's life.
However, this has given us a pretty good use case to see how Event Sourcing works.
In a typical data store, the account details, after all the above transactions have occurred, will be as follows:
However, below is how it will be stored in an event sourcing way:
Deciding the Events
Event sourcing is driven by events. But how do these events get decided on? This question might trouble you initially.
However, the events here are completely dependent on the business case. You could potentially have very simple events such as AccountCreatedEvent, AccountUpdatedEvent, and so on.
In other words, it is a decision you need to take in conjunction with your domain experts. Basically, a good event structure will go a long way in helping you to use event sourcing effectively.
One common process through which events are identified is event storming.
To elaborate, event storming is a rapid, lightweight process of determining the events that can occur in your application. To do so effectively, you need to bring all relevant stakeholders into a common workshop. Then, you can facilitate to make the group hammer out the domain events in your business context. The keyword here is domain event.
These domain events can usually be mapped to aggregates. In other words, aggregates can be thought of as entities. Domain events basically change the state of the aggregate in some way. These events can then be modeled as real events in your application using the event sourcing pattern.
While it can take some practice initially, identifying domain events and the underlying aggregates becomes easier with time.
Why Event Sourcing?
While event sourcing sounds all fancy and stuff, but why should we even consider it?
There are a few compelling reasons.
Event sourcing is one of the best ways to atomically update state and publish an event. As we saw, the traditional way is to persist the current state of the aggregate. However, in event sourcing, the aggregate is stored as a sequence of events. Basically, for every state change, a new event is created and added to the event store. Such an operation is inherently atomic.
However, there are other benefits as well. For example, using event sourcing, you get extremely accurate audit logging for free. In other words, your event store also doubles as an audit log. Basically, this reduces the risk of audit logging being an afterthought.
Another major advantage is the ability to run temporal queries. An event store maintains a complete history of the aggregate. This makes it extremely easy to reconstruct the historical state of the object. In other words, the event store acts as a time machine of sorts. In case of any production issues, you can reconstruct the state of the object at the time the issue occurred in order to investigate.
Last but not least, event sourcing has another major advantage. It provides an incredible amount of business insight. For instance, even in our small example account, we can clearly see the sequence of events occurring on the account. However, indirectly, we are seeing the events occurring in the life of a customer. You can probably guess the kind of insights this can provide to the business in the long run. Apply the same on a million customers and an important aggregate in your business context and you could potentially have a huge factor in your business decisions.
Implementing Event Sourcing
Now that we understand event sourcing and its advantages, let's look at how we can implement it.
For the purpose of this example, we will be implementing event sourcing on our humble account aggregate.
We will be using Spring Boot for our normal application logic. Then, we will use the Axon Framework for managing the heavy-lifting around event sourcing. Also, any event sourcing application needs to have an event store. Basically, an event store is a normal database where events are stored. The beauty of Axon is that it works seamlessly with Spring Data JPA. As a result, we can practically use any database that works with JPA and Hibernate. For the purpose of the example, we will start with the in-memory H2 database.
If you wish, you can read more about Spring Boot and H2 in this post.
More About the Axon Framework
As per the official Axon docs, it is a lightweight framework that helps in building microservices. In other words, it helps solve some of the technical challenges around building microservices.
The framework seems to have been around for quite some time now. It is backed by a company named AxonIQ. So, there is a good chance that it will be well-supported over the coming years and might actually grow.
Now, I don't want to market Axon. But on doing some research it did seem like a pretty solid choice for doing event sourcing. For starters, it integrates very well with Spring Boot and the general Spring world. This makes it quite easy to quickly build an application using event sourcing without worrying about the bells and whistles of managing an event store.
Apart from the above advantage, it also seems less invasive in terms of the code. In other words, you have to write less framework-related code and can focus on your business logic. Later on, as well, it is kind of easy to see your business logic as decoupled from the framework code. In many ways, this is quite similar to the approach the Spring framework takes where it allows you to build your application using simple POJOs.
So, with the scene now set pretty well, we will start looking at the implementation of event sourcing in Part 2.
Published at DZone with permission of Saurabh Dashora. See the original article here.
Opinions expressed by DZone contributors are their own.