3-tier CQRS using Web API as a command/query bus
We recently started using CQRS on a project to provide a new web application to manage a complicated permit process. The CQRS pattern combined with a proper domain model seemed like a good fit for the business logic.
Midway through development of our 2 tier solution (Web <-> Database) we were asked to instead asked to develop a 3 tier solution (Web <-> Api <-> Database) to avoid exposing the database to the web server (no WCF allowed).
Initially the change slowed development and resulted in an explosion in the Lines of Code to functionality ratio. After some thinking we realised it might be possible to use Web API as a command/query bus for our pre-existing CQRS setup, effectively allowing us to "pass-through" the API without needing to write a controller action per command.
This post summarises the ideas behind the working approach we developed. All the code used in this post can be found on Github but the code is very obviously simplified; both to avoid revealing implementation specific details such as security and to allow this post to focus on the concepts.
CQRS
If you're not familiar with CQRS read some of the articles available on the advantages and disadvantages of the pattern. Basically you separate commands (actions which update data) from queries (which read data).
This post will only deal with implementing the query side of CQRS over Web API. Commands should be simpler.
Query
and QueryHandler
interfaces are defined in a separate CQRS class library (ideally Queries and Query handlers live in separate libraries because your web project shouldn't have to reference query handlers).