The flow of simple CRUD (Create, Read, Update and Delete) applications can be described using the following steps:
The controllers layer handles HTTP requests and delegates tasks to the services layer.
The services layer is where most of the business logic lives.
Services use repositories / DAOs to change / persist entities.
Entities act as containers for the values, with setters and getters.
In most cases, for small and medium-sized applications, this pattern is sufficient. However, when our requirements become more complex, the CQRS model may be more appropriate and scalable. To facilitate that model, Nest provides a lightweight CQRS module. This chapter describes how to use it.
In this model, each action is called a Command. When a command is dispatched, the application reacts to it. Commands can be dispatched from the services layer, or directly from controllers/gateways. Commands are consumed by Command Handlers.
With this approach, every application state change is driven by the occurrence of a Command. The logic is encapsulated in handlers. With this approach, we can simply add behavior like logging or persisting commands in the database (e.g., for diagnostics purposes).
The apply() method does not dispatch events yet because there's no relationship between the model and the EventPublisher class. How do we associate the model and the publisher? By using a publisher mergeObjectContext() method inside our command handler.
Now everything works as expected. Notice that we need to commit() events since they're not being dispatched immediately. Obviously, an object doesn't have to exist up front. We can easily merge type context as well:
Now the model has the ability to publish events. Additionally, we can emit events manually using EventBus:
This type of Event-Driven Architecture improves application reactiveness and scalability. Now, when we have events, we can simply react to them in various ways. Sagas are the final building block from an architectural point of view.
Sagas are an extremely powerful feature. A single saga may listen for 1..* events. Using the RxJS library, it can combine, merge, filter or apply other RxJS operators on the event stream. Each saga returns an Observable which contains a command. This command is dispatched asynchronously.
The CqrsModule can also be used for handling queries. The QueryBus follows the same pattern as the CommandsBus. Query handlers should implement the IQueryHandler interface and be marked with the @QueryHandler() decorator.