CQRS/ES #1 A bit of theory

Some time ago I announced series of posts related to the CQRS and Event Sourcing. Today we start our research journey! Generally speaking, why will we deal with this subject? So, I discovered that combo relatively late in my career and besides the advantages and disadvantages of this solution, I have always met with one statement. Implementation is trivial. To be honest, I was like „seriously? Am I that dumb? Fine, we will see”. I will introduce some code in part two. Today we will become more familiar with the theory. Oh, last thing! Having considered the fact that I’m newbie CQRS developer, I’d like to encourage all of you to suggest better / faster solutions if mine won’t be good enough. After this longish introduction let’s dive into the brave new world!

 

CQS – Command Query Separtion

Before we go into the main hero of today’s post, it’s worthwhile to get acquainted with the idea from which directly CQRS derives, called CQS – Command Query Separtion. It was introduced by Bertrand Mayer in 1986 which quite clearly shows that against the prevailing opinion, it’s not such a new thing. So, what is CQS? It’s a principle which says that every method in the system should be categorized to one of two groups:

 

  • Commands – methods that change state of system, but return nothing (void)
  • Queries – methods that return something but do not change state of system

 

I like the explanation of this problem by Martin Fowler:

 

Asking a question should not change the answer

 

It seems quite evident, however from my experience; I know that programmers do not always obey it. Here’s a quite common example:

 

public Item GetOrCreateItem(ItemModel model)
{
 //logic
}

 

We can notice here a little problem. GetOrCreateItem method can behave differently each time. Moreover, we’ve mixed application’s business logic with „stupid” data getting. Consequences could be a pretty dangerous but I ‚ll mention them lately. As you probably guess with CQS this code would look like this:

 

//Query
public Item GetItem(ItemGetModel model)
{
 //logic
}
 
 
//Command
public void CreateItem(ItemCreateModel model)
{
 //logic
}

 

CQRS – Command Query Responsibility Segregation

Nearly 20 years after CQS birth, two great personages i.e. Greg Young and Udi Dahan introduced to world its successor called CQRS – Command Query Responsibility Segregation. The idea was simple. Why do we categorize only methods to the ones which data is taken and to the ones which change the state of our application? We can, after all, design our system so that independent classes deal with these objectives. That is the main difference between these two approaches.

 

Talking about CQS, we are thinking about methods. Talking about CQRS, we are thinking about objects.

 

It’s worth to mention here that there is not the  only one proper way to implement CQRS as for other design patterns. Wait, what? Design pattern? Yes, against general opinion CQRS is just a pattern, not entire architecture. It depends on us to implement it either globally or only in a small piece of our system. Greg Young confirmed that statement:

 

CQRS and Event Sourcing are not architectural styles. Service Oriented Architecture, Event Driven Architecture are examples of architectural styles.

 

Okay so, let’s move on to the graphical representation of CQRS which should help us to understand what kind of implementation we are going to deal with:

 

CQRS1

 

As I’ve mentioned, that’s one of the possible implementations. Scheme contains many components, so let’s discuss them one by one:

 

  • Command – an object that represents user’s intention. For instance, we could create UpdateItemQuantityCommand with two properties: Id, and Quantity.
  • Command Bus – this class has two primary responsibilities. Firstly it ensures the queueing of all commands entering the system. Secondly, it resolves a CommandHandler appropriate for the given command, and it’s invoking the Handle method on it.
  • Command Handler – this class validates received Command first. Then it creates or changes a state of domain object depending on the command. In the end, it saves changes to (Write) database using the repository and it passes generated events to Event Bus.
  • Domain objects (models) – these are the heart of our application by storing whole business complexity. It’s worthwhile to take note of „layer” that surrounds domain objects on a scheme, called Aggregates. It’s a pattern coming from the Domain-Driven-Design. In simple terms, their responsibility is to group logically connected object treating them as a single unit. Martin Fowler explained that well by giving an example of order and order items. Both of these groups can theoretically exist separately, but it is more convenient to treat it as a single, consistent whole. It is also worth mentioning that the changes to the objects in the domain generate events.
  • Event – an object that represents changes which happened in the system. For instance, an ItemQuantityUpdatedEvent could be a consequence of serving the presented previous command.
  • Event Bus – this class has two primary responsibilities. Firstly it ensures the queueing of all generated events. Secondly, it resolves an EventHandler appropriate for the given event object, and it’s invoking the Handle method on it.
  • Event Handler – its task is to persist the changes to the database, which is used to read.
  • Read Database Abstraction – it is nothing more than a layer for getting the data. Implementation is up to you; that’s why the name on the diagram is general.

 

I guess that some of you could feel quite overwhelmed by whole these new things. Therefore I prepared the sequence diagram which better presents flow given in the system. The example shows the realization of the UpdateItemQuantityCommand command:

 

sd

 

ES – Event Sourcing

In all of this, we have to find a role of Event Sourcing. Is that a part of CQRS pattern? Not really. Actually, in the scheme events occurred as a way of synchronizing the two databases. They are in fact part of CQRS, but such use does not realize assumptions of Event Sourcing. The purpose of the ES is in fact, reconstructing the current state of the application (domain objects) based on events stored in the data warehouse called the Event Store. At first, it may seem meaningless, but actually, it’s not. A simple example. In one of my post about isolation levels, I cited an example to illustrate the false update event (I will rewrite that soon). Notice what caused the confusion of data stored there. We stored only one number, which informed the user of its balance. If instead of it an event reporting about increasing the balance by the specific amount was generated, the problem wouldn’t exist. Why? Instead of one information about the balance, we could apply in our domain objects events which gradually would take us to the current condition of the user bank account. And so this simple concept is tremendous in its action. So, how does ES relates to our CQRS diagram? The only change would be replacing the Write DB storage with Event Store. The second change would be a way of getting objects in the domain. Instead of getting them „entirely” now we need to get all of the events generated by the domain object and apply them one by one, thereby obtaining its current state. Simple? And how useful!

 

Why do we need that?

Now we know how we should approach the implementation of CQRS / ES. We are not aware of an answer the fundamental question: why should we do that? Comparing to CQRS typical N-Layer applications seem to be pretty simple and do not complicate the system that much. I have prepared for you a few reasons that may convince you to this concept:

 

  • Asymmetric scalability – using two sources of data, allows to scale our application in the direction of read or write. Moreover, such an approach lets us design databases and select technology so that read/write operations could perform maximally fast. NoSQL? Denormalized database? Why not!
  • Division of teamwork – as you probably noticed the part responsible for reading data is much simpler than that for writing. Moreover, it does not execute any business logic. That gives us the possibility to divide the work in a team so that programmers with less experience can develop some reading without worrying about changing the behavior of our application.
  • Microservices – as described earlier aggregates are the „glue” connecting a logical part of our domain, we can attempt to break our monolithic applications into smaller parts.
  • Restoring the state of the application at any time – as mentioned ES enables us to reconstruct the current state of our application. However, nothing stands in the way to prevent the event apply only to a certain point, thereby obtaining the state of our domain from the past.
  • Audit – Implementing the Event Sourcing we ensure at the same time very enjoyable and detailed audit of our data.

 

What’s next?

That’s all for today 🙂 In the next episode we will begin the technical part of series, in short: we get to implementation! I guess that the subject isn’t simple to understand the first time (at least wasn’t for me), but I hope that we will dispell all doubts together like e.g. in what way will we inform users of the mistake? If you don’t want to miss all of that, I encourage you to follow me on Twitter  or leave a like on my Facebook fan page 🙂

Till next time!

You may also like...