# CQRS

## About

CQRS *(Command Query Responsibility Segregation)* involves separating the **mutation model** from the **query (look up) model**.

{% hint style="info" %}
Reading data has a lot more request volume.

Mutating data has much less volume, BUT must have availability and must be consistent.
{% endhint %}

{% hint style="warning" %}
When having multiple Bounded Contexts, querying data from them starts getting complex and heavy.
{% endhint %}

#### Solutions

What types of solutions CQRS offers.

<table data-view="cards"><thead><tr><th></th><th></th><th></th></tr></thead><tbody><tr><td>Use different patterns inside the project for accessing the database.</td><td>(like <code>DAO</code> vs <code>Repository</code>)</td><td></td></tr><tr><td>Create Snapshot for specific information.</td><td><em>Ex.: The bank will create snapshots of the balance so that it does not have to recalculate data since the beginning.</em></td><td></td></tr><tr><td>Have projection tables with consolidated data for reading only.</td><td><em>You can create intermediate tables that gather information, saving multiple joins to be done from the relational tables. (Kind of like a View)</em></td><td></td></tr><tr><td>Using materialized views.</td><td><em>Use the Database Views, but caches these results.</em></td><td><em>Must ha</em>ve a solution for reloading the data.</td></tr><tr><td>Separate the database for writing and for reading.</td><td></td><td></td></tr><tr><td>Using adequate database types for each purpose.</td><td>(like <code>SQL</code> vs <code>NoSQL</code>)</td><td></td></tr></tbody></table>

## Commands (Writes)

Commands represent transformations caused by **business rules**.

Like:

* Transfer money to an account.
* Enroll a student in a school.
* Make an online purchase.
* Emit a NF.

Its preferable to refer them as modifiers or mutators instead of commands.

{% hint style="info" %}
Domain mutations are excellent work for Domain Models.
{% endhint %}

## Queries (Reads)

Queries are done over data.

Like:

* What is the account balance.
* Which students got the higher grades in the 2° bimester.
* What are the best selling products last month.

{% hint style="warning" %}
Be careful with data calculated on the run, all the time. Maybe they should be calculated on the Domain Model instead.
{% endhint %}

## Usage

The objective would be to replicate the databases, and have one only for reading.

{% hint style="info" %}
This can be facilitated with Event-Driven Architecture.
{% endhint %}

{% hint style="info" %}
People loading reports or visual data, should not disturb the people execution business rules.
{% endhint %}

#### To use CQRS, is it mandatory to separate the written data and read data?

*Ex.: Having mirrored Databases for Read and Write only.*

**Not necessarily**, you must analyze the performance, the persistence model not always is optimized for querying.

#### Should the Read databases be NoSQL?

If the objective is to store multiple non-structured projections, YES.

Use of:

* Cassandra
* MongoDB
* HBase
* Redis
* CouchDB

### With Monoliths, Transaction Scripts

#### Using CQRS

When using simpler architectures, it is a lot more straight forwardd to access the Data base.

There is no real need to use CQRS, since `JOIN` on tables are doable, there is probably only a single database.

{% hint style="info" %}
A usable scenario, would be to speed up some heavy queries with multiple `JOIN`s, but having a table with these data duplicated and flattened.
{% endhint %}

<img src="https://71466530-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHMVa9ug6Ow7EvZCpWe52%2Fuploads%2FDgh9q2fFWIxgF9eVNrME%2Ffile.excalidraw.svg?alt=media&#x26;token=8a57215b-bff4-4bfe-a54e-38d8c94822a7" alt="" class="gitbook-drawing">

### With Domain Model, Clean Arch

#### Using CQRS

In these more complex architectures, expecially when using Repositories, you shouldn't be using them for querying over data, due to:

* Performance loss;
* Excessive filters to be added to the Repository;
* Unability to join data efficiently.

<img src="https://71466530-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHMVa9ug6Ow7EvZCpWe52%2Fuploads%2F40gqEBE5ivdOM44dChMq%2Ffile.excalidraw.svg?alt=media&#x26;token=90af441c-da50-4cf6-99af-ed9f976ed70e" alt="" class="gitbook-drawing">

### With Distributed Services, Microservices

In these types of architectures, the essence is on how to query these distributed data.

#### Using `API Composition` Pattern

{% hint style="info" %}
One way is using `API Composition`, invoking each of the service's interfaces to obtain the data, dumping all to memory.
{% endhint %}

<img src="https://71466530-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHMVa9ug6Ow7EvZCpWe52%2Fuploads%2FBzLtpV4HjFKLyVHhHzWc%2Ffile.excalidraw.svg?alt=media&#x26;token=a71c9275-3688-4212-862c-450f1b30eed5" alt="" class="gitbook-drawing">

#### Using CQRS

One way would be deriving/replicating to a second Read-only database, it is a cheap and fast way. So writes are done in a separate database.

But this still have the same problems as maintaining just one database, meaning, there will be too many `JOIN`s on tables, the tables are probably not built for the bulk READ queries.

<img src="https://71466530-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHMVa9ug6Ow7EvZCpWe52%2Fuploads%2F19A0FBOS5fE102mbUlFV%2Ffile.excalidraw.svg?alt=media&#x26;token=db8ad2d8-4fe3-4863-8d07-d09f7f44c6e3" alt="" class="gitbook-drawing">

The better way is maintaining a separate database that will have `Materialized Views`, which are tables specific for these bulk queries, that have data from all the different services gathered and flattened in one place.

{% hint style="warning" %}
It is possible to update these `Materilized View` synchronously during [Commands](#commands-writes).

It is also possible to use asynchronous and more resilient mechanisms, like publishing events and consuming them on a `Queue`.
{% endhint %}

<img src="https://71466530-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FHMVa9ug6Ow7EvZCpWe52%2Fuploads%2FLcABBsk2jnNAHQrTBytq%2Ffile.excalidraw.svg?alt=media&#x26;token=c5fc54db-0bbe-4e8c-a27c-b3ebae6ea8c1" alt="" class="gitbook-drawing">
