What Is Event Sourcing - Event Store Blog
What Is Event Sourcing - Event Store Blog
Articles
Resources
Event Sourcing
Developers
Download
Event Sourcing is an alternative way to persist data. In contrast with state-oriented persistence that only
keeps the latest version of the entity state, Event Sourcing stores each state mutation as a separate record
called an event.
Model information about activity in the domain as a series of discrete events. Represent each
event as domain object.
All real-life systems store data. There is a vast number of different types of data storage, but usually, Resources
developers use databases to keep the data safe. Computerised databases appeared right after computers
started to enter the business landscape.
Support
Hierarchical databases were quickly outlived by relational databases that started their ascendance in the
1970s when the first query languages called QUEL and SEQUEL appeared. Since the 1980s, when SQL
About
became the standard query languages for relational databases and various RDBMSes like Oracle, IBM DB/2,
and Microsoft SQL Server started to dominate the world of data persistence.
Developers
However, with the rise of object-oriented programming, which became mainstream in the late 1990s,
developers started to struggle to persist objects in relational databases. Such a struggle got the nameDownload
“object-relational impedance mismatch”. Alternative families of databases appeared over the decades to
address the mismatch issues, starting from older object databases to more modern document databases.
Albeit, no matter what database kind the application uses, all that is stored in the database is the current
state of the system. Essentially, all DMBSes support four basic operations for persistence - create, read,
update and delete (CRUD).
System objects usually are persisted as database records - rows in tables or documents. It means that
when the object changes, and the change needs to be persisted, the database record gets replaced by a
new record, which contains updated values.
Products
Use Cases
Resources
Support
About
Developers
Historical record
Download
Use Cases
Resources
Support
About
Developers
Download
Even when such a solution gets implemented and deployed, there is no guarantee that tomorrow or next
year, the business won’t require keeping the record on other state changes. Again, all the history before
the change that would keep such a record will be lost. Another issue with only keeping the current entity
state is that all the changes that happen in the database are, by nature, implicit.
Change history of entities can allow access to previous states, but ignores the meaning of those
changes, so that any manipulation of the information is procedural, and often pushed out of the
domain layer.
Use Cases
Support
About
Developers
Download
Products
Use Cases
Resources
Support
About
Developers
Download
The payment case might be a bit too simple to disclose the difference, so, let’s use another example.
Imagine that the total order amount changes for a different reason. Here is how the change would be
done if we only keep the entity state:
Products
Use Cases
Resources
Support
About
Here an implicit update has been applied to the entity state, and the only way for us to know what
Developers
happened is to look at some sort of audit trail or even the application log.
When we model state changes as domain events, we can make those changes explicit and use the domain
Download
language to describe the change. Below you can see that two completely different operations could’ve
happened that lead to exactly the same outcome if we only look at the final state.
Products
Use Cases
Resources
Support
About
Developers
Download
Use Cases
Resources
Support
About
Developers
Download
Again, the total amount could also change for other reasons, like removing an order item.
A domain event is a fully-fledged part of the domain model, a representation of something that
happened in the domain. Support
Developers
So, Event Sourcing is the persistence mechanism where each state transition for a given entity is
represented as a domain event that gets persisted to an event database (event store). When the entity state
mutates, a new event is produced and saved. When we need to restore the entity state, we read all the
events for that entity and apply each event to change the state, reaching the correct final state of the
entity when all available events are read and applied.
items.Add(newItem);
totalAmount = totalAmount.Add(newItem.LineTotal); Support
}
} About
In this example, we use the Domain Model pattern, so the entity has both state and behaviour. State Developers
transitions occur when we call entity methods, so the flow of execution for any operation would look like
this: Download
Products
Use Cases
Resources
Support
About
If our application uses a Ports and Adapters architecture, we would have an application service, which
Developers
handles the command:
Download
public class OrderService {
EntityStore store;
Now, let’s see what needs to change for our application to use Event Sourcing.
Resources
Event as code
Support
Notice that event properties are primitive types or shared complex types, which All the types
used for events, including shared types, are just property bags (DTOs) and should not contain
any logic. The main attribute of these types is that they must be serializable.
The event now describes the domain-specific behaviour and contains enough information to mutate the
Order entity state.
Producing events
Second, we need to change the entity code, so it will generate an event:
Support
var newTotal = totalAmount.Add(newItem.LineTotal).AsDouble;
Apply(
About
new ItemAdded {
OrderId = id,
Developers
Item = Map(newItem),
Total = newTotal
} Download
);
}
}
At this stage, the AddItem method doesn’t directly mutate the entity state, but produces an event instead.
It uses the Apply method, which doesn’t exist in the Order class yet, so we need to implement it.
Collect changes
Every new event is a change. The Order class should keep track of all the changes that happen during the
command execution flow, so we can persist those changes in the command handler. Such a behaviour is
generic and not unique to the Order class, so we can make an abstract class to isolate the technical work
in it:
Products
Support
We can now change the Order class to inherit from the Entity class, and the code will compile.
However, notice that the entity state doesn’t change when we produce a new event. It might be not aAbout
problem if we only produce one event when handling a command, but that’s not always the case. For
example, when adding a new item we could produce two events: ItemAdded and TotalUpdated toDevelopers
make state changes more explicit and atomic. In some cases, the code that produces consequent events,
but still being in the same transaction, need to know the new entity state, changed by the previous event.
Download
Therefore, we need to mutate the state in-process when we apply each event.
Use Cases
protected abstract void When(object event);
}
Resources
Now, we can implement the When method in the Order class:
Developers
public AddItem(OrderItem newItem) {
if (!CanAddItem(item))
Download
throw new DomainException("Unable to add the item");
Essentially, in order to restore the entity state from events, we need to apply the left fold on all the events
in the entity stream. Support
With all these changes, the Order class public API hasn’t changed. It still exposes the AddItem method
and only the internal implementation is different. About
Developers
Now, let’s get back to the original command handling flow and see how it changed since we started using
events.
In fact, the overall flow is the same, so is the application service code. The only change is how the
EntityStore adapter works. For state-oriented persistence, it is something like putting the entity state to
a document, serialising it and storing it in a document database, and then reading it back. How would it
look when we have an event-sourced entity? We use the same port, so the API doesn’t change. We need to
implement an adapter that can use an event-oriented database, like Event Store.
In terms of persisting objects, the main use case for an event database is to be able to store and load
events for a single object or entity, using the entity identifier. The main difference is that when you use a
relational or document database and use the entity id to get the data, you get a single record, which
directly represents the current entity state. In contrast, when you retrieve an entity from an event
database, you get multiple records for one id and each record in the set is an event.
Products
Therefore, the whole set of events that represents a single entity has one unique identifier. Since we don’t
have a single record, which is assigned to that identifier, we call that event set a stream. The stream is an
ordered collection of events for a single object in the system. The object identifier combined with theUse Cases
object type is often used as the stream name.
Resources
Support
About
Developers
Download
When we read all events from a single entity stream, we can reconstruct the current state by calling the
When method for all the events, in sequence.
With an abstract event-oriented database, the EntityStore adapter would look similar to the code
below:
}
Developers
public T Load<T>(string id) where T : Entity {
var streamName = EntityStreamName.For(entity); Download
var dbEvents = db.ReadEvents(streamName);
if (dbEvents.IsEmpty()) return default(T); // no events
Support
About
Developers
Download
Alexey Zimarev Alexey is the Head of Product Management for Event Store and the author of the book
“Hands-on Domain-Driven Design with .NET Core”. His particular interests are in event-driven
architectures, domain-driven design, distributed systems, and event-sourcing. Alexey contributes to open-
source software as a member of MassTransit and Proto.Actor projects, and a maintainer of RestSharp. He
manages the Domain-Driven Design Norway meetup group and speaks at technical conferences. Follow
Alexey on Twitter at @Zimareff.
Products
Use Cases
Resources
Support
About
Developers
Download
Follow this blog to stay up to date on what’s happening at Event Store:
Products
Use Cases
Resources
Pages Support
Developers
A top-level introduction to the core principles for developers and software architects looking to build event-
sourced systems.
Download
Visit page
Webinars
Resources
Support
Articles
About
Event Sourcing and CQRS
Developers
CQRS stands for Command-Query Segregation Principle. Greg Young described (and named) the pattern
thoroughly in 2010, but the... Download
About us EventStoreDB
Our company Open-source database
Get in touch
Resources
Pricing Sites
Support
Cloud pricing Developers
Github Developers
Discord
Download
Customer logins
Cloud sign in
Support sign in
Follow us
YouTube
Products
Security Terms of use Privacy policy Cookie preferences
Use Cases
© 2023 Event Store Limited
Event Store and EventStoreDB are registered trademarks of Event Store Ltd
Resources
Support
About
Email address*
Email address* Submit Download