CQRS without Multiple Data Sources

One of the most common misconceptions about CQRS is it implies Eventual Consistency. That you must have different data sources for your commands and queries. Meaning you will have a use one data source for commands/writes and an entirely different data source for query/reads. This is simply untrue.

This assumption implies that you’re query/read data source will be eventually consistent with the command/write side. This is because the assumption is your commands will write to its data source, then emit events that will be processed and update your query/read database independently.

If you’re unfamiliar with CQRS, I highly recommend checking some other posts I’ve written about CQRS before reading futher.

Different Models

One of the benefits of applying CQRS is that you can have different representations of your data. Your write model may look very different than your read model.

However, this doesn’t mean you need to have different data sources and use event handlers to build your query model.

Views

If you’re just getting into applying CQRS, you can use the exact same underlying data model for both commands/writes and queries/reads. There’s nothing saying you can’t.

However, if you’re using a relational database you can get all the benefits of tailored query models by mapping your queries/reads models to database views. Or if you database supports it, materialized views.

If you’re using Entity Framework Core, this is pretty straight forward by defining your query types in the OnModelCreating method of your DbContext.

Consistentcy

This means you’re command/write model and query/read models are always 100% consistent. You’re not dealing with eventual consistency.

Another bonus is you’re not writing event handlers to update your read/query database which also eliminates a pile of code and complexity.

From my experience, when applied wrong, eventual consistency can be a giant pain and not at all what you’re users are expecting.

Most often users are expecting to click a button and see the results immediately. Obviously, there are many ways to handle this, but if you’re new to CQRS, my initial recommendation is to keep things as simple as possible and that means keeping data consistent.

Start simple:

  • Create a class that changes state (command) and create a separate class that reads state (queries).
  • Use SQL Views (or materialized views) to map tailored queries.
  • Use something like Automapper for compositing the query result.

Atomic

If using Views isn’t an option, and you’re using the same relational database for both reads and writes another option is to wrap the entire operation in a transaction. This means your operation to modify your database records for the command, as well as modify database records for your queries happen within the same transaction.

I’ll elaborate more on this, eventual consistency, event sourcing and more in coming posts.

Fat Controller CQRS Diet

I’ve blogged a bit about how to implement CQRS without any of the other fluff. You can check out my Fat Controller CQRS Diet blog series as well as a related talk:

If you have any questions or comments, please let me know on twitter as I will focus my posts on those questions and comments.

Follow @CodeOpinion on Twitter

Software Architeture & Design

Get all my latest YouTube Vidoes and Blog Posts on Software Architecture & Design

eShopOnContainers a Microservice based .NET Core Sample Application

eShopOnContainersFinding good sample applications if pretty difficult, if not impossible.  Most are small Todo style applications that are generally very CRUD based.  Thankfully Microsoft has created the eShopOnContainers a Microservice based .NET Core Sample Application.
.NET Core reference application, powered by Microsoft, based on a simplified microservices architecture and Docker containers. This reference application is cross-platform at the server and client side, thanks to .NET Core services capable of running on Linux or Windows containers depending on your Docker host, and to Xamarin for mobile apps running on Android, iOS or Windows/UWP plus any browser for the client web apps. The architecture proposes a microservice oriented architecture implementation with multiple autonomous microservices (each one owning its own data/db) and implementing different approaches within each microservice (simple CRUD vs. DDD/CQRS patterns) using Http as the communication protocol between the client apps and the microservices and supports asynchronous communication for data updates propagation across multiple services based on Integration Events and an Event Bus (a light message broker, to choose between RabbitMQ or Azure Service Bus, underneath) plus other features defined at the roadmap.

eShopOnContainers

Here’s a development environment overview of the of the eShopOnContainers app.  I just want to point out a few pieces that I thought were well done in this sample. eShopOnContainers  

Service Autonomy

Each service (Identity, Catalog, Ordering, Basket, Marketing, Locations) is autonomous.  It owns its own data(store) and does not have any dependencies on any other services.  In order to communicate with other services, it uses an event-driven model via publish/subscriber on an event bus of RabbitMQ or Azure Service Bus. Each service does contain its own HTTP API that provides functionality such as retrieving data as well as performing specific actions.  For example, the Ordering service contains an API project that has HTTP resources for retrieving orders as well as canceling an order.

View Composition

Since each service provides its own HTTP API for retrieving specific data owned within that service, you ultimately need to compose your view from multiple services. Backend-For-Frontends (BFF) patterns are used to provide a single API backend for a specific client type.  For example, the MVC and SPA apps use the Web-Shipping and Web-Marketing BFF while the Xamarin mobile app uses the Mobile-Shopping and Mobile-Marketing BFF.  Ultimately these BFF make HTTP calls to the needed services to compose the data required for the client.

More

I highly recommend checking out the application and digging in a bit.  There are many different services and each has its own individual architecture within it.  Such as the Ordering service using CQRS via the MediatR library in it’s HTTP API.  It also uses some technical DDD patterns as well. If you’re interested in the Backends-For-Frontends, I recommend checking the post by Sam Newman and Chris Richardson. Although a tad outdated, Particular have also a fork of eShopOnContainers but modified to run on top of NServiceBus. If you know of any other solid sample applications beyond To Do lists, please let me know in the comments or on Twitter.
Follow @CodeOpinion on Twitter

Software Architeture & Design

Get all my latest YouTube Vidoes and Blog Posts on Software Architecture & Design

Find MediatR Requests without Handlers

Find MediatR Requests with no HandlersYou’ve run into it.  MediatR throwing an InvalidOperationException when you didn’t have a matching handler for a request.   There’s a fairly simple solution to prevent this: Find MediatR Requests without Handlers.

So here’s some quick code you can throw in a unit test to verify you don’t have any missing handlers.

Find MediatR Requests without Handlers

The above code uses reflection to get all the IRequest<>, RequestHandler<> and RequestHandler<,>.  Also worth mentioning it leverages Autofac for the IsClosedTypeOf method in the linq query.

Usage

Here’s a quick unit test that shows it’s usage for finding Requests without any handlers.  In the sample below I have two Requests without Handlers: MyRequestWithoutHandler and MyRequestWithResultWithoutHandler

Source

All the source code for my example is available on GitHub if you want to try it yourself.

Another useful test would be to verify that your container actually has the the request and behavior handlers registered correctly.  Another post to come with that.

Always love hearing your comments.  Please post them here or on Twitter.