Skip to main content

The CQRS dilemma and related random thoughts

imageI was very skeptical about CQRS (Command Query Responsibility Segregation) some time back, how ever after working on a CQRS implementation for the past few months for a customer in the telecom domain, I see better light. For some reason, there is a wide spread perception that CQRS is only for complex domains, how ever I think any true business system can benefit from CQRS principles. Here are few quick thoughts, mostly rants.

What is CQRS?

The basic idea of CQRS is pretty simple, this is from the CQRS summary post by Greg Young

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.

As simple as that. I suggest you to read/bookmark the below posts.

Code samples to start with (.NET stuff)

So, most of the discussion happening these days is about the application possibilities and implementation details around CQRS, and these are just few random thoughts around the same, and these are not any pointers for anyone.

For a moment, let us forget what exactly is CQRS, let us see how your system or business normally works. The users or stake holders or external system interact with your system in two ways – basically they’ll ask the system to do something (commands), and they also need to view/visualize the state of the system in different ways (queries). In most businesses, the system will be queried not just for the current state, but also for historical changes – i.e, you need to track the history of changes (as in an audit log) and need special logic to capture intelligence about events happened in the past. Say, to answer like "how many users are removing product x from their cart after adding product y". 

You could argue any system that is just CRUD is a database, and yes we can put any decoration on top of it to build some editing features. But any meaningful Business Context involves capturing intent from user, to validate the intent at times, handle it, and provide some meaningful read models to query.

So, I think CQRS allows modeling the domain in a more natural way. You can pick commands directly from the use cases (if well written), and you can focus on what the domain does or what the domain should do when a state change happens, and use this information to construct how different stake holders view the system. In our scenario, we had multiple dimensions/read model snapshots.

Do I need CQRS?

It is all about the ROI, isn't it? Theoretically, you could argue any BC that models a set of business scenarios can be benefited leveraging the CQRS principles, because that means your system will be able to answer a lot of business related questions implicitly. Do you need that or not? That's a business call.

Here is my top three reasons based on my limited exposure towards CQRS based models.

  • The users or stake holders or external system interact with your system in two ways and if you are specifically focused on capturing the user intent– basically in any system, they’ll ask the system to do something (commands), and they also need to view/visualize the state of the system in different ways (queries).
  • In case your system will be queried not just for the current state, but also for historical changes – i.e, you need to track the history of changes (as in an audit log in a stereotypical system) and need special logic to capture intelligence about events happened in the past. Say, as I mentioned, to answer like "how many users are removing product x from their cart after adding product y".
  • Your management/customer thinks it'll add value to them on the long run, i.e, the system will help them have an edge over the competition. Oh yea, you have to sell this to them.

There is going to be a spike in the CapEx, may be because building Task Based/Inductive UIs are more costly than spread sheet like grids/CRUD focused forms where the user has to bring up the entire form to change the status from open to closed or what ever.  Other than that, I think the cost is totally dependent on the design and related details, and the way you implement CQRS along with other DDD patterns.

CQRS and Event Sourcing

CQRS can be a simple separation of commands and queries, but I think the real value is if you tie CQRS with Event sourcing - it allows you to capture the system as how it came to the current state, rather than what it is right now. So, you are adding a new dimension to the system, i.e, the time. And you can take snapshots of the system at different times, and then compare it, that is valuable business intelligence. I think we don't need to see the read model as just a static snapshot of the system at a given time - it can even be derived from the state of the system at two different times.

And you can build read models based on multiple dimensions - to answer questions related to the system's behavior as well. For example, a stereotypical system can't answer even simple questions like "how many users are removing product x from their cart after adding product y" with out explicit design to capture the scenario. In a CQRS system this is implicit.

You can plugin a new dimension that constructs a read model to answer the query. About the cost - I think the key is in bringing in the mindset and selling this idea to the stake holders - even if the initial investment is a bit high, that will significantly improve their ROI and place them ahead of the competition.

How ever, the problem is, the world may be too corrupted with people like us, who were trying hard to persist a single state snapshot of the system in a mismatching ER model and then trying to keep it up to date and worrying about all related issues, to further mess it up with audit logs and all other mining crap when business starts asking critical questions.

Related Reads:

CQRS and REST

Related Reads

Based on the recent experience, I’ve got a feeling that REST and CQRS goes well together, and there is a bit to explore there.   To start with, they way we implemented Commands in one of the recent system is over a REST API, where the URL scheme represents the commands.

Say, for example, if the user need to close and issue, the end point will be like http://server/issue/close   - The end points are used to identify the command handler and pass it to the same. Command handlers are registered in a container, in our case we used MEF to export the command handlers, something like

Message is essentially a key value store as in a dictionary, and this allows us to cope up with versioning.  We had a REST based Querying API too. And we were federating the commands to the results/DTOs as in Hypermedia

i.e, here is an example

[ExportCommandHandler("Issue","Close")]
public void CloseIssueCommandHandler(int id) {..}

I couldn't figure out a defined way for the Task Based UI to find out possible commands based on the current state. Probably this is more or less an implementation related aspect and all of us are free to choose. We could do the validation of the command after it is issued, but in some scenarios, it is better to prevent the user from issuing the command in first place.

I.e, let us consider a DTO,
<issue>
  <id>1</id>
  <description>A bug is trying to hug me</description>
  <otherfields/>
  <link rel="rc:closeissue" url="/issue/close/1">
</issue>

Now, when a user closed an issue, a CloseIssue command has gone in and if the operation succeeds, an IssueClosed event has been logged to our event store - Now, as the issue is already closed, you don't need to (or you should not) provide the CloseIssue action to another user again, because the Issue is already closed by some one.

So, in our scenario, we had some decorators on top of the Query builder to evaluate the current state, so that only the required commands are federated to a returned result. So, the Task Based UI can be more intelligent (and the TB UI is anyway issuing commands based on the DTO information it has).

Related Reads:

Alright, I warned you early enough that these were some random thoughts.  Happy coding!!

Popular posts from this blog

Top 7 Coding Standards & Guideline Documents For C#/.NET Developers

Some time back, I collated a list of 7 Must Read, Free EBooks for .NET Developers, and a lot of people found it useful. So, I thought about putting together a list of Coding Standard guidelines/checklists for .NET /C# developers as well.As you may already know, it is easy to come up with a document - the key is in implementing these standards in your organization, through methods like internal trainings, Peer Reviews, Check in policies, Automated code review tools etc. You can have a look at FxCop and/or StyleCop for automating the review process to some extent, and can customize the rules based on your requirements.Anyway, here is a list of some good Coding Standard Documents. They are useful not just from a review perspective - going through these documents can definitely help you and me to iron out few hidden glitches we might have in the programming portion of our brain. So, here we go, the listing is not in any specific order.1 – IDesign C# Coding StandardsIDesign C# coding stand…

Hack Raspberry Pi – How To Build Apps In C#, WinForms and ASP.NET Using Mono In Pi

Recently I was doing a bit of R&D related to finding a viable, low cost platform for client nodes. Obviously, I came across Raspberry Pi, and found the same extremely interesting. Now, the missing piece of the puzzle was how to get going using C# and .NET in the Pi. C# is a great language, and there are a lot of C# developers out there in the wild who are interested in the Pi.In this article, I’ll just document my findings so far, and will explain how develop using C# leveraging Mono in a Raspberry Pi. Also, we’ll see how to write few minimal Windows Forms & ASP.NET applications in the Pie as well.Step 1: What is Raspberry Pi?Raspberry Pi is an ARM/Linux box for just ~ $30. It was introduced with a vision to teach basic computer science in schools. How ever, it got a lot of attention from hackers all around the world, as it is an awesome low cost platform to hack and experiment cool ideas as Pi is almost a full fledged computer.  More About R-Pi From Wikipedia.The Raspberry Pi

5 Awesome Learning Resources For Programmers (To help you and your kids to grow the geek neurons)

Happy New Year, this is my first post in 2012. I’ll be sharing few awesome learning resources I’ve bookmarked, and will be pointing out some specific computer/programming related courses I've found interesting from these resources.Also, thought about saving this blog post for my kids as well - instead of investing in these Child education schemes (though they are too small as of today, 2 years and 60 days respectively ). Anyway, personally my new year resolution is to see as much videos from this course collections (assuming I can find some free time in between my regular job && changing my babies diapers).1 – Khan AcademyAs I mentioned some time back, you and your kids are missing some thing huge if you havn’t heard about Khan Academy.  It is an awesome learning resource, especially if you want to re-visit your basics in Math, Science etc.With a library of over 2,600 videos covering everything from arithmetic to physics, finance, and history and 268 practice exercises, th…