/
CQRS Pattern

CQRS Pattern

Problem

  • In complex applications, read side and write side can become complicated. Read side can returns data transfer objects (DTOs) with different shapes; Write side can implement compex validation and business logic.

 

Solution

  • Separate the read from the write side :

    • example 1 : implement materialized view for the read side and stored procedures for the write side.

    • exemple 2 : implement 2 different data stores, one for the read side which is a document DB and the other, for the write side which is a relational DB.

image-20240819-181716.png
public class ProductsCommandHandler : ICommandHandler<AddNewProduct>, ICommandHandler<RateProduct>, ICommandHandler<AddToInventory>, ICommandHandler<ConfirmItemShipped>, ICommandHandler<UpdateStockFromInventoryRecount> { private readonly IRepository<Product> repository; public ProductsCommandHandler (IRepository<Product> repository) { this.repository = repository; } void Handle (AddNewProduct command) { ... } void Handle (RateProduct command) { var product = repository.Find(command.ProductId); if (product != null) { product.RateProduct(command.UserId, command.Rating); repository.Save(product); } } void Handle (AddToInventory command) { ... } void Handle (ConfirmItemsShipped command) { ... } void Handle (UpdateStockFromInventoryRecount command) { ... } }

CQRS In Practice : Materialized Views

A materialized view is a physical copy of the table that stores retrieved data from multiple tables in memory, which may result in higher query performance. A materialized view operates like a special notebook where the answers to questions you might ask the database are already written down.

image-20240819-193543.png
CREATE MATERIALIZED VIEW customer_order_totals AS SELECT customer_id, SUM(order_amount) AS total_amount FROM orders GROUP BY customer_id;
SELECT * FROM my_materialized_view;

Related content