Come i comandi Aggiungi / Crea * devono essere gestiti nell'architettura CQRS + Event Sourcing

11

Voglio implementare la mia prima applicazione utilizzando il pattern CQRS insieme a Event Sourcing. Mi chiedo come la creazione di radici aggregate debba essere gestita correttamente. Supponiamo che qualcuno invii il comando CreateItem. Come dovrebbe essere gestito? Dove deve essere memorizzato l'evento ItemCreated? Come primo evento di un nuovo oggetto? O dovrei avere qualche tipo di entità ItemList che aggrega tutti gli elementi e il suo elenco di eventi consiste solo di eventi ItemCreated?

Udi Dahan suggerisce di non creare radici aggregate e usa sempre una sorta di metodo di recupero. Ma come posso recuperare qualcosa che è nuovo e certamente non ha alcun ID assegnato. Capisco l'idea alla base ed è abbastanza ragionevole pensare che un nuovo oggetto sia un oggetto che ha il suo stato composto da zero eventi replicati su di esso. Ma come dovrei usarlo? Dovrei avere un metodo distinto nel mio repository come getNewItem() o rendere il mio metodo get(id) accettando Optional<ItemId> invece?

Modifica: dopo un po 'di tempo di ricerca ho trovato implementazione interessante dei suddetti modelli usando attori. L'autore invece di creare l'aggregato, lo recupera da qualche tipo di repository con UUID appena creato. Lo svantaggio di questo approccio è che consente uno stato di incoerenza temporanea. Mi sto anche chiedendo come posso implementare il metodo delete con tale approccio. Aggiungi semplicemente evento cancellato all'elenco degli eventi dell'aggregato?

    
posta Mequrel 18.03.2014 - 12:02
fonte

1 risposta

13

L'idea nel post di Udi, come ho capito, è che nessun tipo di oggetto appare dal nulla. C'è (quasi) sempre qualcosa, o più specificamente, alcune operazioni di dominio, che hanno causato la creazione dell'oggetto. Proprio come l'esempio di Udi di un utente in realtà nato da un visitatore che si registra al sito. A quel punto e in quel contesto limitato Visitor è la radice aggregata, che viene recuperata dal suo indirizzo IP. Questo visitatore crea quindi il nuovo "elemento", un utente a questo punto, attraverso un'operazione di dominio chiamata Register . Lo stesso vale per il passo precedente, che è un altro contesto limitato: Referrer è l'AR, che viene recuperato dall'URL e che ha un'operazione di dominio chiamata BroughtVisitorWithIp , dove il visitatore è nato.

Udi scrive molto bene anche sulla cancellazione: link . L'idea principale è che tu non cancelli niente, mai. C'è sempre un'operazione di dominio dietro, che vogliamo catturare. Come un ordine annullato, piuttosto che cancellato. Leggilo, è un ottimo post.

Il punto principale qui su entrambi gli account, facendo DDD e in particolare Event Sourcing, è che non dovresti mai fare operazioni CRUD dirette. Se ti trovi in una situazione in cui hai davvero bisogno di inserire, aggiornare o eliminare alcuni dati, e dietro di essi non c'è davvero alcuna operazione di dominio, allora forse DDD e Event Sourcing non sono adatti per per quel contesto limitato . Sei libero di combinare questi due come desideri finché un singolo contesto limitato aderisce a un principio. In questo modo il contesto limitato in stile CRUD potrebbe creare alcune righe nel database, che diventa un'entità e una radice Aggregate in un altro contesto limitato, dove ora puoi recuperare l'AR e non devi crearlo.

    
risposta data 02.07.2015 - 21:20
fonte

Leggi altre domande sui tag