Fundamente și Arhitectură CQRS în .NET
CQRS (Command Query Responsibility Segregation) este un pattern arhitectural care împarte responsabilitățile aplicației între două zone clar definite:
-
Comenzi (Commands) — modifică starea aplicației (ex: adaugă un articol)
-
Interogări (Queries) — doar citesc datele, fără efecte secundare
Această separare aduce claritate în cod, permite validări mai precise și pregătește aplicația pentru scalabilitate și extensibilitate.
1️⃣ Ce este CQRS?
La bază, CQRS propune să nu mai folosim aceleași obiecte și servicii pentru a citi și scrie date. În schimb, separăm complet:
-
✏️ Comenzile – cereri care modifică starea (ex: CreatePost, UpdateUser, DeleteInvoice)
-
🔍 Interogările – cereri care doar citesc informația (ex: GetPostById, SearchUsers, ListInvoices)
📌 Beneficii cheie
Beneficiu |
Explicație |
---|---|
🔄 Separare clară |
Codul de scriere este izolat de cel de citire – mai ușor de înțeles, testat și întreținut |
🧪 Validări dedicate |
Poți aplica reguli diferite pentru ce se scrie vs. ce se citește |
🚀 Scalabilitate facilă |
Poți optimiza sau chiar separa infrastructura pentru read și write (ex: DB replicat pentru queries) |
⚡ Performanță |
Interogările pot folosi DTO-uri ușoare, proiecții sau cache, fără a afecta regulile de business |
🔐 Securitate & audit |
Comenzile pot declanșa evenimente, loguri sau verificări suplimentare |
2️⃣ Structura de proiect recomandată
CQRS funcționează excelent într-o aplicație organizată după principiile DDD (Domain-Driven Design). O astfel de structură promovează separarea responsabilităților și testabilitatea.
📁 Structură pe layere:
🔍 Detalii pe layere
✅ MyApp.Application
-
📦 Aici trăiesc Command-urile și Query-urile
-
✔️ Contine Handlers, Validators, DTO-uri
-
🤝 Comunicarea se face prin MediatR: Send(new CreatePostCommand(...))
🧠 MyApp.Domain
-
Definiția modelului de business
-
Entități, ValueObjects, agregate, interfețe (IPostRepository)
-
Nu conține referințe către infrastructură sau MediatR
🧱 MyApp.Infrastructure
-
Implementările pentru interfețele din Domain sau Application
-
ApplicationDbContext (EF Core), Repositories, fișiere, servicii de e-mail, etc.
🌐 MyApp.API / MyApp.UI.Blazor
-
Controlere sau pagini UI
-
Aici se primesc request-urile și se trimit mai departe către Application (prin MediatR)
-
Nu conține logică de business
🧩 Exemplu de flux
🏁 Ce urmează
În următorul articol, vom construi primul Command complet: CreatePostCommand, cu handler, validare, mapare și salvare în bază de date. Vom introduce MediatR și FluentValidation și vom vedea cum această abordare aduce claritate și extensibilitate.