CQRS - validation current state of aggregate

42 views Asked by At

Could you help me with a shopping cart use case? I use CQRS (Axon framework). I have got an aggregate ShoppingCart with command and event handlers AddProduct, ProductAdded, RemoveProduct, ProductRemoved. I need to solve a use case:

  1. A customer adds a product to a shopping cart. The shopping cart and added product is persisted in db.
  2. But before next visit of shopping cart, the product id sold out.
  3. Before cart is displayed, I need to remove sold out product.

How to find out, that ShoppingCart aggregate is in inconsistent state (contains sold out product)? When remove product from shopping cart? When the shopping cart is displayed, CQRS is in Query side.

2

There are 2 answers

2
Gerard Klijs On

There are several ways to solve this problem, which depend on how you want to handle this from the consumer perspective.

One way is to 'reserve' a product as soon it's in the shopping card. This means customers are always sure they can buy what's currently in their basket. This might prevent the product from being bought by another customer as well. So, with this, you likely have some timeout/deadline to release the items back in stock. Taking this approach, you might be better off with having a wishlist instead of a shopping card as the primary target of products. Another way would be to try to reserve all the products that were in the shopping cart the last time it was logged in on the user logging in. That way he doesn't need to know they were gone and back, and you can offer some information on the items that were out of stock in the meantime.

Another way is to delay the reservation till you move to the checkout phase. In this case, you might still have an 'ItemSoldOut' event in advance, so you can already remove it from the projected shopping card (and maybe add the date it's expected to be back in stock).

There are many other options, depending on what is important. I think the most important bit is that placing it in the shopping cart, is just the user making clear the intent to buy those items. I don't think the aggregate in that way is inconsistent as soon as an item goes out of stock.

2
David Guida On

You could solve this by emitting events. Assuming that your Carts are being persisted, when an Order is placed publish an "Order Placed" event to a queue.

One of the Consumers can retrieve the Order, then check for sold-out Products in it. If you find some, query for Carts referencing them and process an update.