Cosa è CQRS Pattern

Cosa è CQRS Pattern

In questo articolo spieghiamo Cosa è CQRS Pattern dando una definizione ed entrando nei dettagli dell’argomento.

CQRS

(Command-Query Responsibility Segregation)

Si intende un pattern software che separa le operazioni di comando (o aggiornamento) da quelle di query (o lettura) nelle applicazioni.

Introduzione – Cosa è CQRS Pattern

CQRS è un pattern architetturale software (acronimo) correlato a un termine coniato in precedenza, il CQS.

Questa pagina spiega CQRS e CQS, illustrando come uno derivi dall’altro, i benefici di CQRS, i suoi principi fondamentali, nonché alcuni fraintendimenti comuni riguardo al pattern.

Cosa significa CQRS?

CQRS sta per Command Query Responsibility Segregation. Si tratta di un pattern architetturale software basato sulla segregazione delle responsabilità dei comandi e delle query all’interno di un sistema.

Cosa è CQRS Pattern?

CQRS consiste nella separazione delle responsabilità tra i comandi e le query in un sistema. Ciò significa che stiamo segmentando verticalmente la logica applicativa. Inoltre, stiamo separando la mutazione dello stato (gestione dei comandi) dal recupero dei dati (gestione delle query).

CQRS è stato definito da Greg Young:

“Command and Query Responsibility Segregation usa la stessa definizione di Comandi e Query adottata da Meyer e sostiene il punto di vista che essi debbano essere puri. La differenza fondamentale è che in CQRS gli oggetti vengono divisi in due entità: una contenente i Comandi e l’altra contenente le Query.”

È importante notare che gli “oggetti” nella definizione originale non sono collegati allo storage, ma ai gestori. Con CQRS, si creano pipeline differenti per comportamenti di business specifici, invece di utilizzare uno storage separato.

Cos’è il CQS? E come si relaziona con CQRS?

Il CQS è un pattern di progettazione e l’acronimo sta per Command Query Separation. Esso stabilisce un concetto fondamentale che definisce due tipi di operazioni in un sistema:

  • Comando: esegue un’azione (un task);
  • Query: restituisce informazioni.

Secondo questo principio, non dovrebbe esistere una singola funzione che svolga entrambe le operazioni.

Il termine fu creato da Bertrand Meyer nel suo libro Object-oriented Software Construction (1988, Prentice Hall), ed è nato nell’ambito del lavoro sul linguaggio Eiffel.

CQRS riprende il principio definitorio del CQS e lo estende a oggetti specifici all’interno di un sistema, uno per il recupero dei dati e uno per la modifica degli stessi. In questo senso, CQRS rappresenta il pattern architetturale più ampio, mentre il CQS si configura come il principio generale del comportamento.

Benefici di CQRS – Cosa è CQRS Pattern

Costruire l’architettura della propria applicazione secondo i principi di CQRS offre numerosi vantaggi:

  • Confini chiari tra i comportamenti del sistema:
    Fornisce indicazioni specifiche su come strutturare l’applicazione in relazione al comportamento.
  • Maggiore aderenza alla logica di business:
    Il codice e l’architettura sono segregati in base alle operazioni di business, facilitando il focus sul caso d’uso aziendale.
  • Accoppiamento ridotto:
    La logica risulta coesa e meno interconnessa, rendendo più semplice creare applicazioni modulari e facilmente manutenibili.
  • Riduzione del carico cognitivo:
    Grazie alla divisione verticale, il codice correlato viene mantenuto insieme. Per modificare il codice esistente o crearne di nuovo, non è necessario comprendere l’intera architettura o logica di business, facilitando così la concentrazione su compiti specifici.
  • Scalabilità, ottimizzazioni e cambiamenti architetturali semplificati:
    Mantenendo il codice in compartimenti separati, è più facile ottimizzare una singola pipeline lasciando intatte le altre, permettendo di concentrarsi sulle ottimizzazioni critiche per il business.
  • Predicibilità:
    La segregazione garantisce regole operative ben definite. Con una separazione netta tra logica di scrittura e di lettura, si riduce il rischio che una query modifichi inaspettatamente lo stato dell’applicazione, evitando così un “spaghetti code”.

Principi Fondamentali

Il principio fondamentale di CQRS è la separazione tra i comandi e le query e le rispettive funzioni. Questi due elementi svolgono ruoli essenzialmente differenti all’interno di un sistema, e separarli consente di ottimizzare ciascuno in base alle necessità, vantaggioso soprattutto nei sistemi distribuiti.

Alexey Zimarev ha spiegato in questo modo la differenza tra comandi e query:

“A livello generale, CQRS afferma che le operazioni che innescano transizioni di stato devono essere descritte come comandi, mentre qualsiasi recupero di dati che vada oltre le necessità dell’esecuzione del comando deve essere definito come query. Poiché i requisiti operativi per eseguire comandi e query sono spesso diversi, gli sviluppatori dovrebbero considerare l’utilizzo di tecniche di persistenza differenti per ognuno, segregandoli di conseguenza.”

Comandi

Un comando è un’istruzione, una direttiva per eseguire un compito specifico. Esso rappresenta l’intenzione di modificare qualcosa. Bertrand Meyer ha scritto:

“Un comando (procedura) esegue un’azione ma non restituisce un risultato.”

Un comando deve trasmettere l’intenzione dell’utente. Come spiegato da Alexey Zimarev, la gestione di un comando dovrebbe comportare una singola transazione su un aggregate; in sostanza, ogni comando deve definire in maniera chiara una modifica ben precisa.

I comandi costituiscono il modello di scrittura (write model), che dovrebbe essere il più vicino possibile ai processi di business.

Query

Una query è una richiesta di informazioni. Tornando a Bertrand Meyer:

“Una query (funzione o attributo) restituisce un risultato, ma non modifica lo stato.”

Una query esprime l’intenzione di ottenere dati o informazioni sullo stato dei dati da una specifica fonte, senza modificarli. Poiché non causa modifiche, non è necessario che interagisca col Domain Model.

Le query compongono il modello di lettura (read model), che dovrebbe essere derivato dal modello di scrittura. Inoltre, questo modello non deve essere necessariamente permanente: nuovi modelli di lettura possono essere introdotti senza impattare quelli esistenti, e possono essere eliminati e ricreati senza perdere la logica di business o le informazioni, dato che queste ultime sono conservate nel modello di scrittura.

CQRS ed Event Sourcing

CQRS fu introdotto da Greg Young nel 2010, all’incirca nello stesso periodo in cui emerse il concetto di Event Sourcing. Young lo descrisse come un “passo verso l’Event Sourcing”.

In un sistema basato su Event Sourcing lo stato degli oggetti di dominio non viene memorizzato esplicitamente; si memorizzano invece le modifiche apportate a quello stato. Lo stato viene quindi conservato come una serie di eventi, ciascuno rappresentante un’operazione di business. I modelli di lettura vengono costruiti a partire da questi eventi e sono solitamente tenuti in un database separato, ottimizzato per le esigenze di query.

L’Event Sourcing si integra bene con CQRS, poiché gli eventi rappresentano il risultato delle operazioni di business. In questo modo, CQRS, che per sua natura separa le operazioni aziendali, trova in Event Sourcing un partner ideale.

È importante comprendere che Event Sourcing e CQRS non dipendono l’uno dall’altro: è possibile avere un sistema event-sourced senza utilizzare CQRS, oppure implementare CQRS senza ricorrere all’Event Sourcing. I due concetti funzionano bene insieme, ma non sono interdipendenti.

Leggi la Guida per Principianti all’Event Sourcing per ulteriori dettagli.

CQRS e DDD

Il Domain Driven Design (DDD) è un approccio metodologico per ottimizzare la comprensione, da parte di un team, di uno specifico ambito di problema e per operare efficacemente al suo interno. Esso prevede l’adozione di un linguaggio ubiquo, utilizzato sia dagli utenti di business che dal team di sviluppo, il quale facilita la traduzione dei concetti problematici in soluzioni software funzionanti.

CQRS e DDD sono concetti separati e ortogonali. Non è necessario utilizzare CQRS per applicare il DDD, né il contrario. Quando usati insieme, il DDD può fornire un contesto delimitato (bounded context) derivato dal dialogo con il business, mentre CQRS definisce come le operazioni vengono fatte fluire attraverso il sistema. Pur essendo allineati a livello di principio, DDD e CQRS non sono interdipendenti.

Errori Concettuali Comuni su CQRS – Cosa è CQRS Pattern

1. “I comandi e le query devono essere eseguiti su database separati, e tutto deve essere memorizzato in database differenti.”

Non è necessariamente vero: ciò che deve essere separato sono i comportamenti e le responsabilità. Questa separazione può avvenire a livello di codice, nella struttura del database o, se necessario, su database differenti. Non esiste il requisito che i dati debbano essere conservati in database separati.

Approfondendo, CQRS non necessita nemmeno obbligatoriamente di un database: potrebbe infatti essere implementato utilizzando, ad esempio, un foglio di calcolo Excel o qualsiasi altro contenitore di dati. Come spiegato in un articolo di Oskar Dudycz:

“Nulla impedisce l’utilizzo di un database relazionale, persino la stessa tabella per lettura e scrittura. Se preferisci, puoi continuare a usare un ORM. Non c’è nulla che impedisca a un comando di aggiungere o modificare record mentre una query recupera dati dalla stessa tabella, purché manteniamo la separazione nella nostra architettura.”

CQRS si applica al comportamento di un sistema, non al luogo in cui i dati vengono memorizzati. È fondamentale ricordare che il pattern riguarda il comportamento e non lo storage, per creare applicazioni CQRS efficienti.

2. “Può essere utilizzato solo insieme al DDD, e bisogna avere entrambi per realizzare l’Event Sourcing.”

Esiste anche l’errata convinzione che CQRS debba necessariamente essere impiegato insieme al DDD e che entrambi siano indispensabili per l’Event Sourcing. In realtà, puoi applicare CQRS senza dover padroneggiare il DDD e, allo stesso modo, è possibile realizzare un sistema event-sourced senza utilizzare né CQRS né DDD. I concetti funzionano bene in sinergia, ma non sono strettamente dipendenti l’uno dall’altro.

3. “CQRS crea problemi di consistenza eventuale.”

Separare comandi e query e gestirli in maniera differente può comportare che un sistema diventi eventualmente consistente. Esiste l’idea errata che i sistemi a consistenza eventuale siano meno precisi a causa dei ritardi temporali, e che la separazione di comandi e query in CQRS comporti inevitabilmente ritardi e, di conseguenza, problemi di consistenza.

La realtà è che molti sistemi, a prescindere dal pattern adottato, possono soffrire di consistenza eventuale in presenza di ritardi tra il ricevimento di un input, la sua registrazione e il successivo recupero. Questi ritardi sono generalmente dell’ordine di millisecondi, ben al di sotto delle tolleranze della maggior parte dei sistemi. Implementando CQRS, la consistenza eventuale non rappresenta un problema maggiore rispetto ad altri pattern.

4. “I sistemi CQRS necessitano sempre di code di messaggi.”

Non necessariamente. Le code di messaggi, come RabbitMQ e Kafka, permettono di inviare messaggi tra il modello di scrittura e quello di lettura a seconda delle esigenze. Se il sistema è sufficientemente semplice, ad esempio basato su viste di database differenti (oppure, come già menzionato, un foglio Excel), le code di messaggi non sono indispensabili.

Progettando il sistema con la filosofia CQRS, è possibile far interagire tra loro database differenti. Ad esempio (per citare la descrizione di Oskar), si potrebbe utilizzare un database relazionale per il modello di scrittura e un database documentale per quello di lettura. In tale contesto le code di messaggi risultano utili per mantenere aggiornati i modelli di lettura in caso di modifiche nel modello di scrittura.

(fonte)

Innovaformazione, scuola informatica specialistica promuove la cultura IT applicata in maniera consapevole ed affianca le aziende nella formazione nei team di sviluppatori e DevOps. Trovate l’elenco corsi per aziende sul nostro sito a questo LINK.

INFO: info@innovaformazione.net – tel. 3471012275 (Dario Carrassi)

Vuoi essere ricontattato? Lasciaci il tuo numero telefonico e la tua email, ti richiameremo nelle 24h:

    Ti potrebbe interessare

    Articoli correlati