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, Account is an aggregate in this application.

Now, let’s assume the following transactions occur on a particular account:

  • Creation of account with 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 an ice-cream for your girl-friend. Withdrawal of 20 USD.
  • The girl-friend didn’t like the ice-cream. And so, you had to buy another one. Withdrawal of 50 USD.
  • You forgot to pay the rent. Landlord imposed a penalty. Withdrawal of 100 USD.
  • Account set to HOLD status because of negative balance.
  • Deposit 100 USD to the account. Breathe 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:

Account#AmountCurrencyStatus
ABCD56782385.00USDACTIVE

However, below is how it will be stored in Event Sourcing way:

Aggregate_IdEventEvent Payload
ABCD567823AccountActivatedEvent{…}
ABCD567823AccountBalanceUpdatedEvent{…}
ABCD567823AccountHeldEvent{…}
ABCD567823AccountBalanceUpdatedEvent{…}
ABCD567823AccountBalanceUpdatedEvent {…}
ABCD567823AccountBalanceUpdatedEvent {…}
ABCD567823AccountBalanceUpdatedEvent{…}
ABCD567823 AccountActivatedEvent{…}
ABCD567823 AccountBalanceUpdatedEvent{…}
ABCD567823 AccountCreatedEvent{…}

Deciding the Events

Event Sourcing is driven by events. But how to even decide the events? 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 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 be usually 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 be then be modeled as real events in your application using Event Sourcing pattern.

While it can take some practice initially, identifying domain events and the underlying aggregates becomes easy with continued discussion.

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 up 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. 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 like a time machine of sorts. In case of any production issues, you can reconstruct the state of the object at the time of issue to investigate.

Last but not the least, Event Sourcing has another major advantage. It provides an incredible amount of business insight. For instance, even in our small example of 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 have understood 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 Axon Framework for managing the heavy-lifting around Event Sourcing. Also, any event sourcing application needs to have an event store. Basically, 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 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 now backed by a company named AxonIQ. So, there are good chances that it is 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 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. Since this post has already run pretty long, the implementation will continue in Part 2.


Saurabh Dashora

Saurabh is a Software Architect with over 12 years of experience. He has worked on large-scale distributed systems across various domains and organizations. He is also a passionate Technical Writer and loves sharing knowledge in the community.

4 Comments

Nicolò Scarpa · April 11, 2019 at 3:52 pm

Great article. Thank you!

    Saurabh Dashora · April 12, 2019 at 12:15 pm

    Thanks for the compliment!! Happy to know it helped.

Peter · July 12, 2019 at 6:20 pm

Great article. Can you advise on how to extend this example by using Kafka or any MQ as Event bus( This question has been going on around in the web and it would be great if you can share some samples.

    Saurabh Dashora · July 13, 2019 at 3:48 am

    Hi Peter, thanks for the feedback!

    Though I don’t have a sample right now on using something like Kafka or RabbitMQ, I’m working on such an example for a future post. However, I have an example where I have used Axon Server as the Event bus in an Event Sourcing + CQRS setup. Here’s the link to that post which also has a code sample on Github.

Leave a Reply

Your email address will not be published. Required fields are marked *