A canonical example of a simple e-shop.
Let's say a user adds some items to a basket and clicks "Checkout". A "Create Order" command gets issued. Now, before actually creating an order record with status "Payment Expected" and corresponding order lines in a db, we have to check that the items that the user selected are still available (maybe some items were available when the user added them to the basket but not anymore). And we also have to reserve them, so that they do not suddenly disappear while the user is still checking out.
So my question is how to perform this "check and reserve" routine? The way I see it I have multiple options:
- In the "Create Order" command handler use
ProductStockRepositoryto reserve the products and then on success useOrderRepositoryto create an order. Meaning, we use multiple repositories in a single handler. - Do not use
ProductStockRepositoryin the "Create Order" handler directly, instead, create aProductStockServiceand invoke methods on it to check and reserve the products. We still use multiple repositories in a single handler, but the usage of the stock repository is abstracted. - Create an internal "Reserve Products" command and dispatch and await it from inside the "Create Order" command handler.
- "Checkout" button sends a "Reserve Products" command instead of "Create Order". In the "Reserve Products" handler we try to reserve the products and on success invoke a "Products Reserved" domain event. A corresponding event handler fires, in which we create an order.
- Some other way?
This is not a question about how to best model an e-shop checkout flow. The above is just an example. I would imagine there could be many similar scenarios in many different applications.