What Is CQRS?
Today I want to talk about Command Query Responsibility Separation (CQRS). I have noticed some developers using CQRS as a synonym for Event Sourcing. Even though Event Sourcing is related to CQRS, the two concepts are distinct. Event Sourcing is a high-level pattern for recording commands coming into a system. The big idea with Event Sourcing is that the state of the system at any point in time can be recreated by ‘replaying’, in the correct order, the application state changes to the initial system condition.
Anyway, I’m getting distracted. We’re here to look at CQRS, not Event Sourcing. We’ll examine Event Sourcing another time.
These terms are also known to us under a different set of monikers: reads and writes.
Commands, or writes, alter the data within a system. In this context, a ‘write’ has little to do with the traditional idea of writing to disk. Think of it more as a logical rather than a physical write. It’s a system state change—whether to memory, disk or remote service.
Queries, or reads, are requests for data from a system. Again, we are referring to logical reads rather than physical reads. The data can be read from disk, memory, and so on.
OK, so what is CQRS?
CQRS is the idea that we should compose our systems of command and query operations and keep these separated whenever possible.
Because it’s confusing to encounter a function that queries for data and at the same time changes data. The reverse is also true—functions modifying state shouldn’t return a value—we haven’t asked for data.
An example may help.
What do you make of this method signature?
bool SetStatus(bool newStatus);
Judging from the signature alone, it appears to set a status. But what about that return value? What is its purpose? Why does this state-changing method return a boolean value? Is it the value of the updated status? Maybe it’s an indicator as to whether the update operation succeeded?
We’re left scratching our heads. It’s a command with query aspects. Confusing.
CQRS offers wise counsel: Avoid mixing query and command behaviour.
As much as you can, make it one or the other, not both.
Why as much as you can?
I find it beneficial when commands creating new system state return the new object.
public async Task<Customer> Register(CustomerRegistration registration);
This method tries to register a new customer in a system. If the method succeeds, it returns the newly created
Customer. A return value seems appropriate—the returned
Customer object likely contains essential identifiable information, such as a
What if the method does not succeed?
It will throw an appropriate exception relaying the specific problem.