In one of my numerous attempts to create a neat approach to CQRS, this is yet another attempt to remove all the protocol that CQRS requires. I love bootstrapping new projects and experimenting with new approaches, and this is another step that improves efficiency. It is a natural evolution to one of my other CQRS playgrounds: Scritchy.
The conventional CQRS approach requires you to write command - and event classes, to wire up your commands and event handlers to the relevant AR’s, saga’s and viewmodel builders.
I removed some of the clutter in that process with Scritchy. Scritchy uses conventions to wire up the commands and events to the relevant components. This makes CQRS a lot less verbose while still offers the same advantages.
Scritchy v2 ?
While this is a good attempt, it still requires you to write the dreaded event - and command classes. Having pushed some best practices/usages/libs to some enterprise teams in the past, I noticed the following: any change that adds extra steps/work to the process makes acceptance harder by devs, as most people are usually trapped in a certain approach, and they do not see an advantage in having to write more code to do the same thing. If they do not need to write all the “protocol”/extra classes, you have removed yet another step that might slow down acceptance of the practice.
The new approach I am about to tell you about in this blog post completely hides the messages from the dev, i.e. the dev can just use a conventional method call, and messages are created underneath.
This is a possible approach to the problem, but I tend to think that the majority of the CQRS evangelists and practitioners value explicitness over pragmatism. I love the explicitness and clarity of their examples and implementations, but in the real world most people start to think: “Wow, that is a lot of code to simply add an item to the stock; are they nuts ?”.
Having experienced the fallacy of the explicitness in a startup attempt, my brain got tickled to find fast and neat approaches to a pretty established conventional path. I think this one is pretty close.
So without further ado, here I will show you ALL THE CODE required to implement a complete CQRS app:
The domain: Bank account
Let us first start with some sequence diagrams to introduce you to the problem domain:
Nothing spectacular here; yes, I do realize it is a boring sample, but we need a well-known domain to explain it IMO; suggestions for an alternative domain are welcome!
Orchestrates the transfer between 2 accounts
Verifies uniqueness of the account; I do realize on rare cases there might be an error here (when using async processing one might have eventual consistency), but I consider the effort in fixing the error by hand less then the cost to implement it on the domain.
The code above is all that is needed for the domain, i.e. no events or commands etc… isn’t that neat ?
In order to show you what else is needed, I added all the server-side code as well, so you have an idea how much code you need to implement a complete app
This is an approach to CQRS that removes the need to write message classes; it uses a combination of serializing method invocation on a dynamic together with conventions to build a system where messages are completely hidden from the user. Talk about removing infrastructure from the code!
I assume there will be a lot of opponents to this approach, as this gives room for typos etc. However, I do believe that this approach combined with TDD/BDD could be for CQRS what rails was for MVC : a pragmatic approach that allows you to just write code at blistering speed without a lot of added protocol.