EventSourcing: A matter of definition
Tags: eventsourcing, architecture
Published: 2023-11-03 12:57:08

EventSourcing is a straightforward **pattern** to both use and understand. However, why do we encounter numerous strong opinions, challenges, or even failures?
The primary reason is usually due to confusion.
In this article, I will attempt to elaborate on my thoughts by demystifying the definitions in order to mitigate this confusion.

## The Definition

Thanks to the community's advocacy, and particularly the efforts of Oskar Dudycz, we can observe a decrease in the level of confusion between EventSourcing and [EventStreaming](https://event-driven.io/en/event_streaming_is_not_event_sourcing/) or [EventDriven](https://event-driven.io/en/dont_let_event_driven_architecture_buzzwords_fool_you/).
Sometimes, it's also easier to grasp a pattern when we initially learn [when it should not be applied](https://event-driven.io/en/when_not_to_use_event_sourcing/).

In summary, Mathias Verraes's [ definition](https://verraes.net/2019/08/eventsourcing-state-from-events-vs-events-as-state/) is exceptionally clear and concise:

> A system is EventSourced when:
>
> - the single source of truth is a persisted history of the system's events;
> - and that history is taken into account for enforcing constraints on new events.

If the EventSourcing definition is well-understood, we are already halfway there. However, to reach that point, it's also necessary to understand what an **EventStore** is in practice.
Event stores are essentially [key-value databases](https://event-driven.io/en/event_stores_are_key_value_stores/) with [features](https://github.com/ylorph/RandomThoughts/blob/master/2019.08.09_expectations_for_an_event_store.md) such as atomic writes, optimistic concurrency or idempotency. The key usually consists of a name and an ID, while the value is an ordered list of events. This key-value pairing is commonly referred to as a **stream** aka **history**.

## Stream's lifecycle

Keep it **short**! Which means short enough to be able to read the entire stream without any performance issues.
To achieve this, prior **modeling** is crucial.
[Event Modeling](https://eventmodeling.org/) is an excellent method to discover and describe a system using an example of how information has changed within them over time. During the modeling we can define **boundaries** and **independent streams** therefore how to keep them short.
It's always less expensive to refine or redo a modeling rather than realizing it was a mistake after the implementation or the release.

If this is not possible, my two cents is to avoid EventSourcing altogether! It's worthless.
Big streams are typically anti-patterns and are disguised as CRUD operations, cumulative data or [command sourcing](https://thinkbeforecoding.com/post/2013/07/28/Event-Sourcing-vs-Command-Sourcing).

For instance auditing is one of the outcomes of EventSourcing, but we don't do EventSourcing solely for the purpose of auditing. So it shouldn't be used for updating entities info. There are other suitable patterns for this.

**Snapshots** technique is too complex as well and must be at the very bottom of the decision tree.

## State VS Projections

The final boss! Which is the confusion between the state and projections. if we aren't familiar with earlier definitions, the failure might occur swiftly. But this one can heart slowly. It's hidden behind many tricks and fixes.
However it's an easy boss to fight because it's again a matter of definition.

### State

The state is **private**. It’s built only **in-memory** each time we load the history. That’s all!
As said before It's used to enforce constraints on new events.
Jérémie Chassaing's [explanation](https://thinkbeforecoding.com/post/2021/12/17/functional-event-sourcing-decider) is quite straightforward:
1. **Reduce** the history by evolving each event `state -> event -> state`, to get the current state.
2. **Decide** `command -> current state -> events`, to get the command's behavior as new facts.
3. **Append** new events to the history.

### Projections

On the other hand, projections are **public** and it's very important to point out that there could be many of them.
Every time new events are appended to history, projections are triggered right after.
Like the state the history is replayed, but this time, it's in order to know how to update the read model.

What's interesting with projections and so read models, is that what is projected is concise and simple and doesn't contain all the internal state and not necessary data. They are optimized for the view and it's cheap to have many of them. No need to have a complex relational databases.

Common misuses are to project the state, to project from one event and not from the history, to not optimize the read models for views, or to make a canonical or monolithic model.

## Conclusion

EventSourcing is a straightforward pattern to both use and understand. However, it's crucial to grasp the definitions, regardless of implementation details.