CQRS ed Event Sourcing: Il nostro primo progetto andato in produzione – Parte 4 Implementiamo un api per l’approvazione di un prestito

Per sviluppare Soisy abbiamo utilizzato symfony2broadway: prendendo come esempio uno dei casi d’uso dell’applicazione (opportunamente semplificato), in questo post vi mostreremo come l’abbiamo implementato.

Questo lo scenario: il cliente che ha richiesto un prestito dovrà fornire diverse informazioni (codice fiscale, nome, cognome ecc) . Alla fine di questo flusso verrà generata la richiesta di approvazione del prestito. L’approvazione avviene in tempo reale senza tempi di attesa.

Vediamo cosa succede lato backend quando viene invocata l’api per richiedere l’approvazione:

Command bus e repository per il read model Loan sono stati registrati come servizi nel container. In questo ci viene in aiuto il BroadwayBundle che registra dei servizi e mette a disposizione comandi da console per creare o cancellare l’event store.

Il comando viaggia sul command bus e viene gestito dal relativo Command Handler. Broadway utilizza la convezione handleNOME_COMANDO

Dopo che l’aggregato è stato ricostruito, viene chiamato il metodo approve.

Alla fine di ogni metodo di un aggregato viene chiamato il metodo apply che permette di collezionare una serie di eventi, che successivamente verranno salvati nell’event store grazie al repository utilizzato nel Command Handler.

In un approccio CQRS puro, avremo salvato l’aggragato vero e proprio. In event sourcing salviamo gli eventi, che rappresentano lo stato del nostro aggregato.

Come detto negli articoli precenti, una volta salvati gli eventi vengono pubblicati dall’event bus e mandati a tutti i projector che sono in ascolto. Broadway utilizza la convenzione handleNOME_EVENTO.

Questo metodo del projector aggiorna il read model e lo salva.

Il controllo torna al controller symfony che esegue una query ottenendo il read model aggiornato e lo restituisce al chiamante.

E’ importante notare che tutto il flusso avviene all’interno di una singola richiesta PHP, quindi in maniera sincrona. Nel caso in cui ci sia l’esigenza di renderlo asincrono c’è un interessante approccio che prevede l’utilizzo di code per la proiezione dei dati e quindi la costruzione dei read model.

Nel prossimo (e ultimo post) trarremo le conclusioni su questa esperienza che tuttora stiamo portando avanti anche su un altro progetto.