Event-Driven vs Event-Sourced: A Common Misunderstanding
The terms “event-driven” and “event-sourced” are often used interchangeably, while in reality, the two are very different concepts.
Join the DZone community and get the full member experience.
Join For FreeIn today’s world of software development, systems containing some sort of event constructs are increasing in popularity. While this is primarily driven by message-based communication mechanisms, events are also used in different scopes and contexts. The frequent use of the term “event” leads to confusion, which is often observed in discussions about various software architectures among people who are new to these concepts. The terms “event-driven” and “event-sourced” are often used interchangeably, while in reality, the two are very different concepts. In this article, we are going to explore the key characteristics of each, explain how they differ, and how they complement each other. We will focus on clarifying the key differences, not a deep dive into each concept.
Before we dive in, let’s clarify the definition of an “event” in both event-driven and event-sourced systems. An event is an immutable record describing something that has happened in the past. Therefore, the data that an event contains cannot be changed. Immutability and description of the past are fundamental characteristics of events.
Event-Driven
Event-driven architecture (EDA) is an architectural style that primarily uses events as a communication mechanism between various components of a larger system, or between systems. Events are handled asynchronously in a fire-and-forget manner, i.e. the publisher does not wait for a response from consumers. Other parts of the system that subscribe to the event handle it and can trigger larger workflows composed of further events. For example, a microservice-based system may use events to communicate the occurrence of a fact in one microservice. Those events can be handled by consumers in other microservices, which in turn can emit their events to communicate their changes.
- Events are published in a publish-subscribe manner, allowing multiple consumers to handle the same event simultaneously.
- Each consumer receives its own copy of the event.
- The asynchronous nature of EDA can often lead to eventual consistency. This means that the state of the system might not be instantaneously reflected across components.
- EDA systems typically, but not always, leverage a message broker to transmit events from the publisher to consumers.
- Components often use two types of events: domain and integration. Domain events are internal to the components that emit them, while integration events are used for communication between components.
- Typically used by most if not all components in a particular system, with each publishing and subscribing to a subset of events.
Event-Sourced
Unlike EDA, which is an architectural style leveraging events for communication, Event Sourcing (ES) is a persistence mechanism. Events are used to reflect changes to the state of an entity (or other constructs such as an aggregate in Domain-Driven Design) and to reconstitute that state. Upon completing a domain operation, a sequence of events is stored as a stream linked to a particular entity. For example, a set of actions performed on a shopping basket may result in the following events:
- Shopping started
- Item added
- Item added
- Item removed
- Item added
Upon reconstituting the basket’s state, these events are loaded in chronological order and replayed to update the state one by one. The resulting basket will contain two shopping items.
Event sourcing can be described by the below key characteristics:
- After completing an operation, the entity contains new event(s) reflecting the nature of the change(s) which are then saved to an event store (database).
- Events are strictly linked to a specific entity.
- Typically, events participate in a limited-in-scope, strongly-consistent manner. A sequence of new events will not persist if another process appends events to the stream simultaneously.
- New events are persisted transactionally- either all or none get saved.
- Events are loaded from the stream to reconstitute the entity’s state.
- Limited in scope to a single component. A larger system can contain heterogeneous persistence mechanisms, where only a subset uses ES.
Different Yet Complementary
When comparing the characteristics of EDA and ES, it becomes clear that the two are very different. Indeed, they address fundamentally different aspects of software design. While EDA is an architectural style for communication, ES is a persistence mechanism for entities’ state. However, these differences do not mean that the two approaches are mutually exclusive. On the contrary, EDA and ES often go hand in hand complementing each other.
In such a setup, a component using ES processes business logic and stores its entity’s state in an event-sourced manner. At some point, an event will be published indicating the completion of an action that other components participating in EDA might be interested in. It may only be that one particular event or an aggregation of data from multiple events which needs to be handled elsewhere. In either case, a publisher will map this event(s) to an integration event and publish it, thus allowing its consumption in other components.
The distinct nature of EDA and ES is also their strength — each approach focuses on a different area, but together they contribute to a broader system, enabling an audit trail and fine detail of changes in one component, and leveraging EDA to communicate selected changes to other components.
Published at DZone with permission of Ernest Sak. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments