Il vantaggio di ragionare ad Eventi

Sebbene sia possibile adottare approcci CQRS su architetture classiche è indubbio che il paradigma CQRS va a braccetto con il concetto di DOMAIN EVENT, questo perché è possibile costruire i QueryModel direttamente elaborando lo stream di eventi del dominio, azzerando di fatto ogni dipendenza dello storage e soprattutto applicando logiche di generazione del QueryModel (Denormalizzatori) su eventi del “passato”.

In questo piccolo esempio fatto su GitHub su cui stiamo giocando io, Alessandro ed Andrea un esempio molto semplice e primitivo di gestione di querymodel viene fatto su una struttura basata su EventSourcing, dove lo storage è gestito dalla libreria EventStore di joliver. In questa struttura gli eventi di cambio stato vengono persistiti su MONGO, ma se si vuole gestire il QueryModel su database SQL non vi è problema alcuno, visto che l’unico punto di contatto sono gli eventi, nessuno obbliga ad usare le stesse tecnologie per risolvere problemi radicalmente differenti (persistenza eventi e interrogazione)

Supponiamo questo scenario, lancio la mia applicazione client, e creo un paio di InventoryItem inviando un paio di comandi CreateInventoryItem command:

image

questo scatena la creazione di due aggregate root nel BOUNDED CONTEXT del magazzino, ed essendo tutto gestito con EVENT SOURCING in realtà io ho solamente dei commit fatti sul database di storage degli eventi, nel mio caso Mongo.

image

In questo caso come potete vedere ho un evento InventoryItemCreated, ma la domanda ora sorge spontanea, come faccio a mostrare all’utente la lista degli InventoryItem a magazzzino con la relativa quantità? Questo richiede un QueryModel ad hoc che contenga i campi che vogliamo far vedere all’utente e per comodità li vorrei in un database SQL acceduto con NHibernate, perchè mi rende molto facile la gestione e mi permette di scrivere poco codice. Inoltre NH ha un provider LINQ decente, per cui mi viene semplice scrivere codice per le query.

La soluzione è semplicemente scrivere un componente che si registra agli eventi di interesse per costruire il QueryModel (nel nostro caso l’InventoryItemCreated e l’InventoryItemStocked) per creare questa view. Una volta costruito l’assembly, basta metterlo nella stessa cartella del server, aggiungere il file di configurazione di NHibernate e far ripartire il server.

image

Quello che accade è che l’infrastruttura rileva un nuovo handler, e durante la configurazione viene richiesto il replay degli eventi, perchè l’inizializzatore dell’handler verifica che il database è in uno stato “obsoleto”, dato che è vuoto, non contenendo nemmeno una tabella. L’infrastruttura base pertanto non fa altro che verificare che l’handler gestisce due eventi, per cui preleva dall’event store tutti gli eventi di quel tipo ed effettua il replay.

Il risultato è che abbiamo l’autogenerazione del nostro QueryModel.

image

La comodità di questo approccio è che se per qualche ragione il QueryModel deve cambiare di formato, è sufficiente andare ad aggiornare il denormalizzatore, cambiare il numero di versione e questo scatenerà al successivo riavvio un replay degli eventi :) ed il gioco è fatto. Inoltre come potete vedere ci sono molti InventoryItem di test, non solamente i due che ho creato prima di aggiungere il denormalizzatore. Gli altri InventoryItem erano stati creati nel passato e come potete vedere sono presenti nel QueryModel.

Se siete interessati ai dettagli il codice è online, nei prossimi giorni se il tempo ed il caldo mi permetteranno XD, descriverò in breve dettaglio alcune soluzioni adottate, ricordando che questo progetto è comunque un playground su cui stiamo “sperimentando”, ma i cui concetti andranno in produzione prossimamente 😉

Gian Maria.

Comments are closed.