Estoy trabajando en una pequeña aplicación de ejemplo para aprender los conceptos de CQRS y el abastecimiento de eventos. Tengo un Basketagregado y un Productagregado que debería funcionar de forma independiente.
Aquí hay un pseudocódigo para mostrar la implementación
Basket { BasketId; OrderLines; Address; }
// basket events
BasketCreated { BasketId; }
ItemAdded { BasketId; ProductId; Quantity }
AddItemSucceeded { BasketId; ProductId; Quantity }
AddItemRevoked { BasketId; ProductId; Quantity }
ItemRemoved { BasketId; ProductId; Quantity }
CheckedOut { BasketId; Address }
Product { ProductId; Name; Price; }
// product events
ProductReserved { ProductId; Quantity }
ProductReservationFailed { ProductId; Quantity }
ProductReservationCancelled { ProductId; Quantity; }
Los comandos son bastante similares a los eventos, usan el nombre imperativo y no el tiempo pasado.
En este momento estos funcionan bien independientemente. Emite un comando AddItemy crea un ItemAddedevento en el Basketagregado que hace lo que necesita hacer con el estado de la 'Cesta'. Del mismo modo, para el producto, el comando y los eventos funcionan bien.
Ahora me gustaría combinar esto en un proceso que sería algo así (en términos de comandos y eventos que suceden):
El administrador de procesos haría lo siguiente:
on BasketCreated: CreateShoppingProcess
on ItemAdded: ReserveProduct
on ProductReserved: SucceedAddingItem // does nothing, but needs to be there so that the basket knows it can check out
on ProductReservationFailed: RevokeAddItem
on RemoveItem: CancelProductReservation
on Checkout: CreateOrder // create an order and so on...
Las preguntas a las que no pude encontrar respuestas definitivas son:
- ¿Necesito persistir en el administrador de procesos? Parece que sí, pero no estoy seguro
- Si lo hago, necesito guardar los eventos para el administrador de procesos. Sin embargo, los eventos que está escuchando están vinculados a los agregados. ¿Añado el ID del proceso a esos? ¿Tengo eventos separados solo para el administrador de procesos? Cómo hacer esto y mantenerse lo más SECO posible
- ¿Cómo sé para qué cesta son los
ProductReservedeventos? ¿Está bien tener unBasketIdsobre eso, o es esa información que se filtra? - ¿Cómo mantengo una relación entre eventos, cómo sé qué
ItemAddedprodujo quéProductReservedevento? ¿Paso a lo largo de unEventId? Esto parece extraño ... - ¿Debo implementar el
Basketcomo administrador de procesos en lugar de un agregado simple?
Después de un poco más de investigación llegué a esto: una saga es algo que mantiene sus propios eventos y escucha eventos desde el exterior. Básicamente, es un agregado que también puede reaccionar a eventos que suceden fuera de su propio pequeño mundo.
Un administrador de procesos trabaja con los eventos desde el exterior y envía comandos. Su historia se puede reconstruir a partir de los eventos que ocurrieron en los Agregados que comparten un identificador común como un ID de correlación.