Я працюю над невеликим прикладом програми, щоб вивчити концепції CQRS та пошуку подій. У мене є Basket
агрегат і Product
агрегат, який повинен працювати незалежно.
Ось декілька псевдокодів, щоб показати реалізацію
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; }
Команди досить схожі на події, використовуючи імперативну назву і не минулий час.
Зараз вони працюють добре незалежно. Я видаю команду AddItem
, і вона створює ItemAdded
подію на Basket
сукупності, яка робить те, що потрібно робити зі станом "кошика". Так само для продукту команда та події працюють просто чудово.
Зараз я хотів би об'єднати це в процес, який би йшов приблизно так (з точки зору команд та подій, що трапляються):
Менеджер процесів зробив би наступне:
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...
Питання, на які я не зміг знайти остаточних відповідей, це:
- Чи потрібно наполегливо керувати процесом? Здається, як я, але я не впевнений
- Якщо це зробити, мені потрібно зберегти події для менеджера процесів. Однак події, які він слухає, прив'язані до сукупностей. Додавати ідентифікатор процесу до них? Чи є у мене окремі події лише для менеджера процесів? Як це зробити і зберегти як можна ДРУГІ
- Як я можу знати, для якого кошику проводяться
ProductReserved
події? Чи добре це мати іBasketId
на них, чи це теча інформація? - Як я можу підтримувати взаємозв'язок між подіями, як я можу знати, яка
ItemAdded
подіяла якаProductReserved
подія? Я проходжу уздовжEventId
? Це здається дивним ... - Чи повинен я реалізувати
Basket
як менеджер процесів замість простого агрегату?
Після ще кількох досліджень я прийшов до цього: Сага - це те, що зберігає власні події та слухає події ззовні. В основному це агрегат, який також може реагувати на події, що відбуваються поза його власним маленьким світом.
Менеджер процесів працює з подіями ззовні та надсилає команди. Його історію можна відновити з подій, що відбулися на агрегатах, які мають спільний ідентифікатор, наприклад, кореляційний ід.