Event Sourcing

The trouble with the traditional approach to persistence is that it maps classes to database tables. For example, the order aggregate is mapped to the order table and the items on an order are mapped to the order_item table. This leads to a so-called object-relational impedance mismatch, the difference between a tabular relational schema and the graph structure of the rich domain model with complex relationships. Another limitation is that it only stores the current state of an aggregate. The previous state is lost after the aggregate is updated and we need additional mechanisms to implement regulatory instruments and audit logging. And lastly, the traditional approach doesn’t support publishing domain events, which are useful for synchronizing data in microservices. That is where the event sourcing pattern comes in.

Event Sourcing is a solution that enables us to maintain data changes as a sequence of immutable events. Each event is added to the data storage as a new record. In contrast to the basic CRUD operation, the events are used for each operation, and they are added to the data storage, also called an event log or journal. It can be a click of a button, sending a request to another service or a purchase in ecommerce, each of those actions that changes the application’s state, are events. We need the events for tracking, auditing, logging, etc… so the idea of the event sourcing is to store the events.

Events are stored as immutable records in the event store, meaning the new events are added as a new record and cannot be changed. However, the effect of an event can be altered by adding another event that will overwrite the original event. For example, if we add an event OrderPlaced with incorrect total amount and we want to change this event, we have to add OrderVoided and another OrderPlaced with the correct total amount. Those characteristics can be used for creating application’s snapshots, auditing purposes, tracking or restoring data. Replaying the events from the event log also enables us to rebuild the application’s state at any time, and the current state is presented from all of the events. This approach allows us to track the changes in the history and reproduce errors from the previous state.

Let’s take a look at some of the fundamental topics in the event sourcing:

  • events – represents something that happened in the business domain. They are considered as the source of truth, because the current state of the application is derived from the events. Events are immutable and usually contain unique metadata such as the timestamps, unique identifier (ID) and the event name. Besides that, data which is populated with the state, is also present in the event model.
  • event store – is an event-native database where events are stored. Those kinds of databases are different from traditional databases. They are designed to store history of changes and the state is represented by the log of events. New events are appended to the previous event and are stored in chronological order. Events are immutable and cannot be changed.
  • event streams – stores the events that refer to a particular domain and present the source of truth for the domain objects and contain the full history of the changes.
  • projections – provide a view on the event based data-model. Projections should not be confused with the state. The state is derived from the events; projections are an interpretation of the raw data. They are methods of populating our read models, for example to create invoices and reports in financial applications.

Event sourcing is useful in the financial industry, such as banks, trading platforms and insurances. This industry requires mechanisms that guarantee high consistency of the data and enable them regulatory and revision activities. It is also suitable in the logistics, transport and retail industry for solutions that require up-to-data record and for tracking various user activities.