What is CQRS and how to implement?

Asked

Viewed 8,566 times

14

CQRS (Command and Query Responsibility Segregation) is one of those acronyms that we come across and we can’t fully understand its meaning and use.

What is CQRS and how to implement?

  • There’s a nice article by Martin Fowler (in English) about it. In the footnote there’s a link to the Portuguese translation. https://www.martinfowler.com/bliki/CQRS.html

  • Also wanted to learn CQRS, the problem is not reading, but implement.

  • 1

    There’s also this link which is quite enlightening on the subject.

  • CQRS is the separation of the reading and writing of the data into two models distinct (being model the definition of entities and the relationship between them). It can be useful when the need to read the data (here, "query") requires a very different design from the writing needs of this data (here, "command"). When reading and writing doesn’t require a different design but you just need to address performance issues or differentiated views of data in some queries, there are much simpler options. So I guess it’s not worth a description of as implement CQRS.

3 answers

15


CQRS

Command Query Rsponsibility Segregation, or CQRS, is a standard software development architecture that summarizes separating reading and writing into two models: query and command, one for reading and one for writing data, respectively.

Reprodução / Mike Fowler

  • Query model: responsible for reading BD data and updating the graphical interface.

  • Command model: responsible for writing data in the BD and validating the data. Its interaction with the graphical interface is only to receive the data to be written.


Today, modern applications has new concepts of availability, performance, functionality and usability (we are talking about applications of "office").

Following such a structure, this type of application must be available in an architecture designed to support thousands of users, such as very few users (and of course still in the standards of the modern application structure). Like it or not, it’s a concept of SCALABILITY, your software/service following its own use.

When we talk about software scalability itself we are talking about about having a code and architecture that is easy to maintain, of increasing its functionality, of several people working on it.

Eventually we can use the term to indicate that the software can be used by a large amount of users (customers). In the sense of persons or enterprises
Source

A simple example: let us think of an ATM withdrawal. Thousands of people (and now you) accessing the same database, recording and reading data all the time. Ignoring the queues, imagine if it took hours to make a single withdrawal?! A chaos.

Regarding CQRS, another important definition is: nothing is what it seems. Yeah, that’s exactly right. If you perform a query in the database (query model) and for some reason these data are changed (command model), what you see is not necessarily the updated data. Working with this data always updated can cause a huge loss of performance (remembering, your application is modern!).

The proposal to divide the tasks may seem a little more interesting now. But no, not only that, model segregation is about separation physical and/or logical of data.


In the simplest possible diagram of CQRS, we have:

Implementation

There is no single way to implement CQRS in your application, can be done in a simple or very complex way, depending on the need. Regardless of how CQRS is implemented always entails extra complexity and it is therefore necessary to evaluate the scenarios where you really need to work with this standard.
Source

Example of implementation

From here down, a simple CQRS pattern. Already forward, removed from here.

The CQRS architecture for an ASP.NET MVC project

Create some class library projects, query stack and command stack, and reference the two from the main web server project.

The stack of query

The query stack class library is only concerned with data recovery. It uses a data model that corresponds to the data used in the presentation layer as close as possible. You rarely need any business rules here, as they apply to state-changing commands.

The domain model pattern popularized by the DDD is essentially a way to organize domain logic. When you do front-end queries, you are only dealing with part of the application logic and use cases. The business logic of the term usually results from the application-specific logic union with the invariable domain logic. If you know the persistence format and presentation format, just map the data as you would in a good old ADO.NET/SQL query.

It is useful to remember that any code you can call from the application layer represents the system’s business domain. Therefore, it is the invariable API that expresses the main system logic. In optimal conditions, you must ensure that no inconsistent and incongruous operation is possible even through the exposed API. Then to impose the read-only nature of the query stack, add a wrapper class around the default Entity Framework context object to connect to the database, as shown in the following code:

public class Database : IDisposable
{
  private readonly QueryDbContext _context = new QueryDbContext();
  public IQueryable<Customer> Customers
  {
    get { return _context.Customers; }
  }
  public void Dispose()
  {
   _context.Dispose();
  }
}

The Matches class is implemented as a Dbset collection in the Dbcontext base class. As such, it provides full access to the underlying database and you can use it to configure queries and update operations via LINQ to Entities.

The key step in setting up a query pipeline is to allow access to the database only for queries. This is the function of the wrapper class, where Matches is exposed as a Iqueryable. The application layer will use the database wrapper class to implement targeted queries in bringing the data to the presentation:

var model = new RegisterViewModel();
using (var db = new Database())
{
  var list = (from m in db.Customers select m).ToList();
  model.ExistingCustomers = list;
}

Now there is a direct connection between the data source and the presentation. You are just reading and formatting the data for display purposes. You expect the authorization to be imposed on the port through user interface logons and restrictions. Otherwise, you can add more layers throughout the process and enable data exchange through Iqueryable data collections. The data model is the same as the database and is 1 to 1 with persistence. This model is sometimes called layered expression trees (LET).

There are some things you should observe at this time. First, you’re in the read pipeline where business rules usually don’t exist. All you can have here are filters and authorization rules. These are well-known at the application layer level. You don’t have to deal with data transfer objects along the way. You have a persistence model and real data containers for the display mode. In the application service, you end up with the following standard:

var model = SpecificUseCaseViewModel();
model.SomeCollection = new Database()
     .SomeQueryableCollection
     .Where(m => SomeCondition1)
     .Where(m => SomeCondition2)
     .Where(m => SomeCondition3)
     .Select(m => new SpecificUseCaseDto
       {
         // Fill up
       })
     .ToList();
return model;

All special data transfer objects in the code snippet are specific to the presentation use case you are implementing. They are just what the user wants to see in the Razor view, which you are creating and the classes are inevitable. In addition, you can replace all Where clauses with ad hoc Iqueryable extension methods and activate all code in the domain-specific language written dialog box.

The second thing to note about the query stack is related to persistence. In the simplest form of CQRS, the command and query stacks share the same database. This architecture makes the CQRS similar to classic CRUD systems. This makes it easy to adopt it when people are resistant to change. However, you can create the back-end so that the command and query stacks have their own databases optimized for their specific purposes. Synchronizing two databases then becomes the other problem.

The command stack

In CQRS, the command stack concerns only the execution of tasks that modify the application’s state. The application layer receives requests from the presentation and organizes the execution by sending commands in the pipeline. The expression "send commands to pipeline" is the source of various types of CQRS.

In the simplest case, sending a command consists of simply invoking a transaction script. This triggers a simple workflow that performs all the steps required by the task. Sending an application layer command can be as simple as the following code:

public void Register(RegisterInputModel input)
{
  // Push a command through the stack
  using (var db = new CommandDbContext())
  {
    var c = new Customer {
      FirstName = input.FirstName,
      LastName = input.LastName };
    db.Customers.Add(c);
    db.SaveChanges();
  }
}

If necessary, you can transfer control to the true domain layer with services and the domain model where you implement complete business logic. However, using CQRS doesn’t necessarily bind you to the DDD and things like aggregations, factories and valuables. You can have the benefits of command/query separation without the extra complexity of a domain model.

More links about implementation

  • 2

    The worst thing is, the CQRS is nothing like this. The author reiterated 3 times that he is only that the pattern consists of just separating readings from writings, but we programmers love to see complexity where it does not exist and there are articles like the ones you consulted that mix 1000 different concepts and destroy the original idea of the pattern.

  • @Bruno Costa It is naive to say that CQRS is nothing like that. To say that ONLY the separation of reading and writing would not render 50 pages of documentation. It is a complicated subject. If we want official sources, we will only have one link and it is over. https://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf

  • 1

    of these 53 pages, 5 are dedicated to explaining what CQRS is (17 to 22). The rest are on other subjects.

  • Being the class RegisterInputModel identical to the Customer This wouldn’t be a way to DRY as there is a change in the Customer this amendment would have to be repeated in Model ?

5

According to the default author it consists only of separating the read operations from the write operations.

When Most people talk about CQRS they are really speaking about Applying the CQRS Pattern to the Object that represents the service Boundary of the application. Consider the following pseudo-code service Definition.

Customerservice

void MakeCustomerPreferred(CustomerId)

Customer GetCustomer(CustomerId)

CustomerSet GetCustomersWithName(Name)

CustomerSet GetPreferredCustomers()

void ChangeCustomerLocale(CustomerId, NewLocale)

void CreateCustomer(Customer)

void EditCustomerDetails(CustomerDetails)

Applying CQRS on this would result in two services

Customerwriteservice

void MakeCustomerPreferred(CustomerId)

void ChangeCustomerLocale(CustomerId, NewLocale)

void CreateCustomer(Customer)

void EditCustomerDetails(CustomerDetails)

Customerreadservice

Customer GetCustomer(CustomerId)

CustomerSet GetCustomersWithName(Name)

CustomerSet GetPreferredCustomers()

That is it. That is the entirety of the CQRS Pattern. There is Nothing more to it than that...

Translation

When most people talk about CQRS they really are talking about how to apply the CQRS pattern to an object that represents the service layer of an application. Consider the following definition of service.

...

Applying the CQRS standard would result in two services

....

That’s it. The CQRS standard is just that. There’s nothing else in it for moreover...

Source - The pattern creator himself wrote this text.

3

As the question contains the C#tag, the most official material I found is:

At first CQRS is to have two Apis, one to make consultations, and another to command the system.

Accidentally (researching about Groovy), I found that this is on fad:

Many microservices implementations will move away from their REST/JSON Beginnings and Truly embrace Event-driven Architectures, with the Hardest problems being Solved by Event Sourcing and CQRS implementations.

Translation:

Many implementations of Microservices will move away from their beginnings REST/JSON and truly embrace architectures oriented to events, with the most difficult problems being solved by Event Sourcing and CQRS implementations.

What is the relevance of my remark?

Answer: Event Sourcing

The example in C# about CQRS that you find there in the link MSDN, seems well oriented to Event Sourcing. Usually, they are implemented together, CQRS and Event Sourcing.

The CQRS Pattern is often used in Conjunction with the Event Sourcing Pattern.

The reason for this is not pertinent at this time (if you are curious, ask another question in Stackoverflow). The problem is that Event Sourcing greatly complicates the implementation of CQRS. The documentation itself talks about it:

The inherent Complexity of the CQRS Pattern when used in Conjunction with Event Sourcing can make a Successful implementation more Difficult

Now, you want to know how to implement CQRS, with or without Event Sourcing?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.