Skip to content

Why would you want to implement CQRS and ES

Sam edited this page Feb 10, 2018 · 3 revisions

Command-Query Responsibility Segregation (CQRS) and Event Sourcing (ES) are two patterns that can be difficult to wrap your head around. These patterns are complex and much time may be required to learn and truly understand what was going on. Hopefully this article will save other you some time, because while CQRS and ES are useful, they're pretty dense and difficult to understand if you're seeing them for the first time, but they promise (and deliver) some ENORMOUS benefits once you get past the initial complexity.

Command-Query Responsibility Segregation

The vast majority of modern application functionality can be summed up in the acronym CRUD:

  • Create
  • Read
  • Update
  • Delete

We create objects, read them, modify them, so-forth. Virtually all functionality in any given app (that isn't trivial) can fall into one of these general categories. CRUD leads to an application model that is relatively simple to understand; such a model may look like this:

CRUD

Source: Martin Fowler

In other words, we have an Application that contains a Model of our data, and uses that Model to query a Database for the data itself. For most applications, this is the correct and even the preferred architecture for a solution.

While this model works for a great deal of applications, as our needs become more complex and reliable, the CRUD model starts to become less and less useful. More intricate applications require a more complex application model (or models), and one possible solution is to use Command-Query Responsibility Segregation (CQRS).

The essence of CQRS is that you use a different model to read the data than you do to modify it. An updated application model would look like this:

CQRS

Source: Martin Fowler

What this allows, among other things, is for the developers to optimise each side (commands and queries) separately for their respective operations. Further, modifications to the models only affect their corresponding applications.

Taken to an extreme, CQRS can enable you to have entire different interfaces, datastores/readstores, even complete technical stacks for the query and command sides of you application. Of course, nothing about CQRS says you have to do any of that; the only thing you need to do to satisfy CQRS is to use different models for commands and queries.

Event Sourcing

The second, and distinct, architectural pattern we'll be using is Event Sourcing (ES). In short, Event Sourcing is a different way of thinking about data storage.

Much of the time, we use datastores that reflect the model of our data. Take, for example, one of the models we used in A Simple Checkboxlist in ASP.NET MVC:

EF Model

Source: Matthew Jones

For this model, we have database tables for Movie and Genre, related by a many-to-many table (which is not modeled as an entity in Entity Framework; in short, this model has 3 database tables but 2 entities). A great number of databases will use similar models; one table per entity, with relationships, keys, constraints, etc. In other words, CRUD data models store the data in its current state.

Event Sourcing advocates that we ignore the CRUD model and instead store the changes made to the data using an append-only store, known as an Event Store. In this architecture, we store all changes made to the data as serialised events, which can be re-run at later time to get us the current state of any object. This pattern allows us to get the state of a given object at any point in time, which is a great help when debugging certain problems. Further, because all events are serialised, we only need one schema/table to represent our entire event store (though you can have more).

One point to make here is that Event Sourcing doesn't store the current state of the data*. Instead, when a particular object is modified, Event Sourcing re-executes all events on that particular object before making the new change. This means that we could have thousands of events executed every time a change is made (*this can be negated via the use of snapshots, which copies of data at a specific point in time, and are then used as starting points for subsequent events).

Using CQRS and ES Together

While these two patterns (CQRS and ES) are orthogonal, they fit together quite nicely. The Event Store from ES becomes CQRS's Write Model, and the design of the Read Model is irrelevant to how ES behaves. A sample model of how the two patterns fit together can be seen in this diagram:

CQRS Diagram

Source: Introducing Event Sourcing from the MSDN

CQRS/ES can be a lot of work to set up without a template, and the benefits of doing so are not always clear. In fact, one of the proponents of this architecture, Martin Fowler, actually recommends not using CQRS unless you have a clear reason to do so. The pattern is most useful in applications in the cloud and those that need to scale both horizontally and vertically and don't mind having to deal with a lot of architectural overhead.

For a more in-depth explanation of these ideas, check out Martin Fowler's blog entries for CQRS and Event Sourcing, or read A CQRS Journey from the MSDN.

Clone this wiki locally