Should you use the Repository Pattern? With CQRS, Yes and No!

The repository pattern is polarizing. Some developers swear you should always use it to abstract data access logic while others think it’s unnecessary if you’re using an ORM. So should you use it? My answer is Yes and No! If you’re applying CQRS and Vertical Slice Architecture you’ll likely want a repository to build up Aggregates. However, for a Query, you may want to just get the data you need rather than an entire aggregate (or collection of aggregates) to build a view model.

YouTube

Check out my YouTube channel where I post all kinds of content that accompanies my posts including this video showing everything that is in this post.

Repository

As with many terms and concepts in the software industry, a repository can mean different things depending on your definition. I’m using the definition from Martin Fowler’s P of EAA Catalog definition.

Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.

https://martinfowler.com/eaaCatalog/repository.html

The key to part for me of that definition is domain objects. Not data models, but domain objects.

CQRS & Vertical Slices

Often I’m using CQRS to separate pathways between writes (commands) and reads (queries) to my database. This allows the definition of two distinct paths that each can decide how they interact with the database, their dependencies, etc. This isn’t top-level architecture but just a decision you can make in various parts of your system.

Should you use the Repository Pattern? With CQRS, Yes and No!

As mentioned earlier, CQRS is a concept that is often confused. Check out my post CQRS Myths: 3 Most Common Misconceptions that should clear up any confusion.

What ultimately happens when you start focusing individually on a command or a query leads to organizing your code around features. A feature can be an individual command or query, or a collection of a few.

A Vertical Slice is a concept of taking everything related to a feature and organizing it together. As mentioned, this becomes a natural fit with CQRS. Ultimately a feature is a single use-case or a defined set of functionality within your system.

Should you use the Repository Pattern? With CQRS, Yes and No!

Vertical Slices are focused on features, not technical concerns. No longer are you organizing and writing code in a layered approach. The layers and technical separation are defined per feature.

This means you can define how each command or query handles various concerns, for example, data access.

If you go back to the definition of the Repository Pattern, it’s for accessing domain objects. Domain Objects that are grouped together are defined as an Aggregate. To interact with the Aggregate, all operations are handled by a primary domain object which is the Aggregate Root.

The common example often used is a Sales Order and all the Line Items. The Sales Order and Line Items are domain objects that form an Aggregate. The Sales Order is the Aggregate Root. All operations are done through the Sales Order and no access is done directly to any Line Items. Check out my post on Aggregate Design: Using Invariants as a Guide for more on how to define and design an aggregate.

This means that I’m only concerned with an aggregate for making state changes. In other words, an Aggregate is required for Commands, not Queries.

This means that we can define to use an Aggregate for any Commands, and simply use a Data Model for any Queries. We do not need an Aggregate for queries because our Aggregate is responsible for state changes.

Also, most of the time when creating a Query, you want data to be shaped a certain way. This doesn’t necessarily require everything within an Aggregate. Because of this, you’re often way over fetching data to build the Aggregate when you only need a subset of the data for the Query.

To illustrate this, here is code from the eShopOnWeb sample application. The Order entity is the Aggregate Root that is returned from a Repository.

The sample code has a Query that is using the IOrderRepository to list all the Orders for the logged-in user.

Since we don’t need the Orders Aggregate, we don’t really need to use the Repository Pattern. The benefit of not using the repository is rather we can select the data we actually need for this use case. In this sample, it was reusing the OrderViewModel to be used when listing all the Orders as well in another route when viewing an individual Order.

This re-use is actually not helpful because the Order Listing page does not need any of the Order Items or the Shipping Address.

Rather, we can define our result explicitly for this use case and fetch exactly the data needed. Again, this use case did not need any order items, the product for those order items, or the Shipping Address. The aggregate is fetching and returning all this data that we do not need.

The Repository Pattern

If I’m applying CQRS and Vertical Slices, it means that on the Command side I’m going to use a Repository to build up and return an Aggregate. An aggregate is a consistency boundary and is responsible for state changes that are controlled by invariants.

On the Query side, since I’m not making any state changes, I do not need an Aggregate. An aggregate is likely way more data that I likely need to transform into the result that I need to create. Queries are specific use cases in ways to return data. A Query is encapsulating that concept including how it’s accessing that data. You could decide to not even use the same library for underlying data access in your Repository as you are in any Queries. CQRS enables that option.

Source Code

Developer-level members of my YouTube channel or Patreon get access to the full source for any working demo application that I post on my blog or YouTube. Check out the YouTube Membership or Patreon for more info.

Related Links

Follow @CodeOpinion on Twitter

Software Architeture & Design

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

Is a REST API with CQRS Possible?

If you’re developing an HTTP API (what most would call REST) how does that fit alongside a Task-Based UI and CQRS? How can you create a REST API with CQRS? For starters, resources don’t need to map to Entities. Second, HTTP Methods don’t need to map to CRUD. Resources can be whatever you want them to be. In which case, they can be commands and queries.

YouTube

Check out my YouTube channel where I post all kinds of content that accompanies my posts including this video showing everything that is in this post.

Resources

In some of my recent videos/blogs about Task Based UIs, I’ve had people ask how CQRS can work with “REST”. The issue is what most think is REST, isn’t actually REST at all. There’s this notion that resources need to revolve around Entities. Specifically that HTTP methods map to CRUD (Create, Read, Update, Delete) around entities.

This is incorrect.

Here’s an example of a typical example revolving around Entities and CRUD. In this case, my entity is a Product in a warehouse.

Then the common pattern is to use HTTP methods mapping to CRUD. Although HTTP methods don’t fully map to CRUD, this again is the common pattern.

So for our Product Entity, our typical API would have an API following this CRUD pattern.

Resources

This misconception that resources should be entities (such as a Product) causes confusion on how CQRS can be applied. The reality is that a resource is whatever you want it to be. It can be an Entity, but it can also represent a Command or a Query.

From the Mozilla Developer Docs:

The target of an HTTP request is called a “resource”, whose nature isn’t defined further; it can be a document, a photo, or anything else. Each resource is identified by a Uniform Resource Identifier (URI) used throughout HTTP for identifying resources.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Identifying_resources_on_the_Web

An Resource can be anything. It does not need to be an entity. It can represent a command or a query.

REST API with CQRS

In order to really apply CQRS, you’re better served with a Task Based UI that will guide users to invoke commands. Command and Queries will be resources.

REST API with CQRS

Making your commands and queries resources makes them explicit. If you were to have only resources as entities, then you would have to infer which command to call for each POST/PUT/PATCH/DELETE based on the request body.

UI Composition

The next most common question is how to do UI composition. If there are multiple services that have resources that need to be called in order to get the relevant data for a UI, how is that done?

One option is to do the composition on the client. The client will call each service to get the relevant data it needs.

This means that there will be a call to each service. For the SKU, name, Description, since that’s owned by the catalog, there will be a call to that resource.

REST API with CQRS

And the same for all other data required, such as the price from Sales.

REST API with CQRS

The other option is to do the composition on the server. This is often referred to as Backend for Frontend.

REST API with CQRS

The server will call the relevant services and compose all the data into one resource that will be returned to the client with all the relevant data it needs.

Source Code

Developer-level members of my CodeOpinion YouTube channel get access to the full source for the working demo application available in a git repo. Check out the membership for more info.

Additional Related Posts

Follow @CodeOpinion on Twitter

Software Architeture & Design

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

CQRS Myths: 3 Most Common Misconceptions

Although Command Query Responsibility Segregation (CQRS) seems to be a term a lot of developers are aware of, I do think the majority have the wrong definition. Like many terms in the software development industry, things over time get confused, and then those confusing ideas propagate. These are the 3 CQRS Myths I see or hear the most often.

YouTube

Check out my YouTube channel where I post all kinds of content that accompanies my posts including this video showing everything that is in this post.

CQRS Myths

I do understand why people can be confused by CQRS as if you do a search, you’re bound to find blog posts that explain CQRS very differently. Some posts get it right, however a lot of others conflate CQRS with other concepts.

So which blog posts are right? Who has the correct definition? How do you even know what I’m writing is correct?

CQRS Definition

Greg Young, who coined the term, used to blog on CodeBetter.com and his own personal site, goodenoughsoftware.net.

Unfortunately, neither of those sites exist anymore. However thanks to archive.org, we can go back to a blog post that Greg wrote in 2010.

Example

Instead of having a single object that has both write & read operations, you would split that into two separate objects. For example:

CustomerService has methods that return state (read) and mutate state (write). In order apply CQRS, we simply need to split these up into separate objects that will do one or the other, but not both.

That’s it. CQRS applied.

So why the confusion?

I assume most of the confusion is because most examples showing CQRS are also showing a bunch of other things, which is where these myths come in.

CQRS Myths

There are so many blog posts that will show a diagram like the one above, that are applying CQRS, but also doing other things.

Myth #1: Multiple Databases

CQRS does not require you to have multiple databases. You can use the same database for writes (commands) as you can for reads (queries).

CQRS Myths

It’s not a physical separation but more of a logical one. If you’re using a relational database, you could create SQL Views that only your query side accesses.

Myth #2: Event Sourcing

Event Sourcing is the concept of storing immutable events derived from actions within your system that represent state change. Greg Young has been at the forefront of Event Sourcing, and since he coined the term CQRS, I can see how Event Sourcing often gets lumped into it.

Most often times if people are referring to both CQRS and Event Sourcing, they will use the label “CQRS/ES”. I think it’s a good idea as I hope it’s preventing more confusion.

You do not need to be Event Sourcing in order to be doing CQRS.

Myth #3: Asynchronous Messaging

You do not need to be using a message bus to apply CQRS. Commands do not need to be asynchronous. Everything can be done in a synchronous request/response manner.

I think this myth stems from people using a message bus along with Event Sourcing so they can create projects for a separate read model.

More

Greg wrote on his blog in 2012 common misconceptions that I don’t think if left us yet. Hopefully, this post shining a light on his original posts help clear things up.

Follow @CodeOpinion on Twitter

Software Architeture & Design

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

Links