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

Enjoy this post? Subscribe!

Subscribe to our weekly Newsletter and stay tuned.

Snapshots in Event Sourcing for Rehydrating Aggregates

Once you understand how Event Sourcing works, the most common thought is: “What happens when you have a lot of Events? Won’t it be inefficient to fetch every event from the event stream and replay all of them to get to the current state?”. It might be. But to combat this, you can use snapshots in event sourcing to rehydrate aggregates. Snapshots give you a representation of your aggregates state at a point in time. You can then use this as a checkpoint and then only replay the events since the snapshot.

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 on using Snapshots in Event Sourcing.

Large Event Streams

I’d guess in most situations, you won’t have a stream with a lot of events because you’ll have a lifecycle to the stream. Meaning an event stream usually has a life where it being and ends. For example, an Order as a lifecycle from when from the OrderPlaced to maybe an OrderShipped. After the order has been shipped, there likely are no more events for that specific order that will occur. However, you could have a stream that is opened ended or possibly has a really long life, such as maybe a product in a warehouse. That event stream could be long-lived as long as you keep selling and having a given product in the warehouse. In these situations, you may have thousands or millions of events depending on the context.

When you have a lot of events, the challenge is you generally will fetch from the Event Store all the events from the very beginning of the stream, and then replay them in your aggregate to build up to the current state. This could take an undesirable amount of time if you have to fetch and replay a significant amount of events.

Snapshots in Event Sourcing

Snapshots are a way of solving this issue by recording the state of an aggregate at a point in time. You then store this state in a separate event stream. Along with the state, you record the version of the last event you processed that represents this state.

For illustration, you can see that the snapshot has our current state, which we’re recording the total quantity on hand. It also captures version (3) which is the last event in our event stream. For my example, I’m creating a snapshot on every 4th event. In reality, at what interval you create a snapshot is totally dependent on your situation. This could be hundreds.

Once more events are added to our event stream, we create new snapshots of the state and keep track of the version they pertain to.

Rehydrating Aggregate

Now instead of replaying all the events from the beginning of the event stream, what we do is first look at the snapshot stream and see if there are any events. But you do so reading the stream backward! So in the example above, we would get the last snapshot in the stream, which has a State with the Qty: 87 and the Version = 11. We will pass the state into our aggregate, then we will query the event stream and start at Version 12. In my example above, it would then retrieve 3 events from that point, which would be replayed in our aggregate.

Here is some example of code from a Repository that is rehydrating an aggregate. That repository is using EventStoreDB as the EventStore.

Before you go down this road, make sure you absolutely need snapshots. They might not be required. Or perhaps you need to implement them for a specific type of event stream that is more open-ended. Keep track of metrics related to how long it takes to replay your aggregates, how many events typically in a stream, then decide if it’s worth adding.

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

Enjoy this post? Subscribe!

Subscribe to our weekly Newsletter and stay tuned.

Decomposing CRUD to a Task Based UI

Moving from CRUD (Create, Read, Update Delete) based UI to a Task Based UI means creating a user interface that makes users’ tasks explicit. Tasks (or actions, commands) are a way to guide a user into the specific actions they can take for a given state or workflow. When you break down by actions, you then can start seeing where the boundaries might lie, which can help split entities into multiple boundaries.

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.

CRUD

For this example, I’m using an Product Entity that contains various properties used in our application.

All the properties should be self-explanatory. If we were creating a CRUD-based UI, we would simply have a page/form that allows the user to set all the various properties.

Task Based UI

When you click the save button, all the data is sent to the server and the entire entity is updated.

So what’s the problem with CRUD?

In some situations, there may not be anything wrong with creating CRUD-based UIs. However, when you start to infer the intent of the users based on what data they are changing is when you’re better off moving to a Task Based UI.

In the CRUD-based UI from above, if a user were to change the price from $85 to $80, then click save, did they just change the price? Was that their intent? Or was their intent to do a price decrease? What other parts of your system need to be aware of that occurring?

Could you notify customers that had that product in their “Wishlist” that the price is now lower?

CRUD Based UIs do not capture the intent of the user. It’s not explicit. You need to derive what the user intent was. In a Task-Based UI, you’re making the users’ actions explicit. Make the implicit explicit.

Boundaries

The first step to building a task-based UI is understanding which properties on your entity change together or are related

Task Based UI

The red (top) box that has the Name and Description could be changed together, or independently. These two likely don’t have much behavior/tasks behind them so they could just be CRUD.

The purple (lower left) box with Price, For Sale, and Free Shipping are likely for sales purposes.

The green (lower middle) box has the Cost and this is for the Cost from the Vendor or Manufacturer. It does not relate at all to the Sale price.

The yellow (lower right) box has the Quantity which is the Quantity on Hand in the warehouse. It does not relate to the cost or the sale price.

Task Based UI

If you take the CRUD Based UI and separate each box into its own boundary, you then can start asking the question, what is the intent of users when they are changing these fields. Why are they changing them? It’s likely different users/roles have an interest in different pieces of data.

Task Based UI

The SKU, Name, Description might be owned by the Catalog service/boundary. This may be totally CRUD in nature. However, the Price might be owned by Sales. Purchasing would own the Cost and the Quantity on Hand would be owned by the Warehouse.

From a user/role perspective, what tasks are they trying to perform when they want to change data within that boundary.

We can see now that Sales you can IncreasePrice or DecreasePrice. If we wanted to increase the Price, we would provide the ability for that specific task/command.

Task Based UI
Task Based UI

If the warehouse did a stock count of a product and determined there weren’t as many on the shelves as what the system says, they would be doing an Inventory Adjustment. They aren’t just updating the QuantityOnHand value, they are explicitly changing the quantity to add or remove from the QuantityOnHand for a specific reason.

Boundaries

Not only have we defined explicitly what users’ tasks/actions are, but we’ve defined boundaries. The concept of a product could live within multiple boundaries/services. You do not need to have an entity live in one single place and it contains all the data for the entire system.

Additional Related Posts

Source Code

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

Follow @CodeOpinion on Twitter

Enjoy this post? Subscribe!

Subscribe to our weekly Newsletter and stay tuned.