Many people have been getting confused over what CQRS is. They look at CQRS as being an architecture; it is not. CQRS is a very simple pattern that enables many opportunities for architecture that may otherwise not exist. CQRS is not eventual consistency, it is not eventing, it is not messaging, it is not having separated models for reading and writing, nor is it using event sourcing. I want to take a few paragraphs to describe first exactly what CQRS is and then how it relates to other patterns.
CQRS Command and Query Responsibility Segregation
Starting with CQRS, CQRS is simply the creation of two objects where there was previously only one. The separation occurs based upon whether the methods are a command or a query (the same definition that is used by Meyer in Command and Query Separation, a command is any method that mutates state and a query is any method that returns a value).
When most people talk about CQRS they are really speaking about applying the CQRS pattern to the object that represents the service boundary of the application. Consider the following pseudo-code service definition.
void ChangeCustomerLocale(CustomerId, NewLocale)
Applying CQRS on this would result in two services
void ChangeCustomerLocale(CustomerId, NewLocale)
That is it. That is the entirety of the CQRS pattern. There is nothing more to it than that… Doesn’t seem nearly as interesting when we explain it this way does it? This separation however enables us to do many interesting things architecturally, the largest is that it forces a break of the mental retardation that because the two use the same data they should also use the same data model.
The largest possible benefit though is that it recognizes that their are different architectural properties when dealing with commands and queries … for example it allows us to host the two services differently eg: we can host the read service on 25 servers and the write service on two. The processing of commands and queries is fundamentally asymmetrical, and scaling the services symmetrically does not make a lot of sense.
Task Based UI
A task based UI is quite different from a CRUD based UI. In a task based UI you track what the user is doing and you push forward commands representing the intent of the user. I would like to state once and for all that CQRS does not require a task based UI. We could apply CQRS to a CRUD based interface (though things like creating separated data models would be much harder).
There is however one thing that does really require a task based UI… That is Domain Driven Design.
The Application Service Layer in Domain Driven Design represents the tasks the system can perform. It does not just copy data to domain objects and save them… It should be dealing with behaviors on the objects… Before going further let’s look at what happened if we did; there would be no verbs in our ubiquitous language except for “Create”, “Delete”, and “Change”. While there exist many domains where this is what the Ubiquitous Language is actually like, you probably should not be using Domain Driven Design for such systems.
The concept of a task based UI is more often than not assumed to be part of CQRS, it is not, it is there so the domain can have verbs but also capturing the intent of the user is important in general. Was this a managerial override or a normal update? Does it make a difference? It depends on what question you want to ask …
Moving on to the next pattern that gets confused into CQRS
For this I want to be clear, when I use this term I am not encompassing all of what is written on the bliki. I am referring to storing current state as a series of events and rebuilding state within the system by replaying that series of events. .
On the command side of the equation, since reads are no longer on the domain, storing events can be a great way of keeping the current state. The value increases more if you decide to have two separate models (a write model and a read model) and you have a need to integrate between the two of them as you will likely be doing that through events. Since you are building the eventing anyway, why not just use the one model to manage your state?
There is no need to use messaging patterns with CQRS. That said, if you separate your data models you will more likely than not use messaging in the integration between the models because it offers interesting possibilities.
Finally I come to the last “pattern” I hate to call it a pattern when it is really a concept that people tend to put into their definitions of CQRS and it goes hand in hand with messaging.
Eventual consistency is also quite often introduced between the services. It is done for many architectural reasons but the largest is that it allows you to increase your scalability and availability. If you remember CAP theorem consistency if given up allows increases in the other two. Eventual consistency is extremely useful in between the models if you have them in a separated fashion but is in no way a property of CQRS itself.
Going through all of these we can see that CQRS itself is actually a fairly trivial pattern. What is interesting around CQRS is not CQRS itself but the architectural properties in the integration of the two services. In other words the interesting stuff is not really the CQRS pattern itself but in the architectural decisions that can be made around it. Don’t get me wrong there are a lot of interesting decisions that can be made around a system that has had CQRS applied … just don’t confuse all of those architectural decisions with CQRS itself.
On a personal note it feels so weird to be writing to a blog again. Writing for a book is hard, writing for a blog is easy. Pages in the book average me an hour or more while this took me just over 30 minutes to write. The less formal style allows one to write in a more stream of consciousness manner. Anyways, hope everyone enjoys the blog posts that will be pouring in over the next short period.