Can a Query change the state of the database #754
Replies: 2 comments 1 reply
-
CQRS is more about guidelines than rules, but they tend to be good guidelines. In your example, there's no reason why the query should trigger the change in the basket - it's the item being out of stock that is the problem. When the item goes out of stock, an event could trigger, which could update the basket at that time regardless of whether someone is looking at it. At the same time, it might be worthwhile to send a notification to the customer letting them know something in their basket is now out of stock (and would they like to be notified when it's available again, etc). All that said, if the overhead of implementing events, etc. is not worth it and it's simpler overall for you to just do the update when they next look at the basket, you can do that. Do the write as part of the GET operation, as you describe. Just realize you're trading off some architectural benefit for your pragmatic need. What are you trading? Well, it will make it harder to implement caching of your GETs (both on your server, but also on any server between you and the client. HTTP supports caching GET calls unless you add headers prohibiting this). If a user makes a GET on their cart and receives a cached response, you won't have a chance to update their cart. But this isn't really any different than if you had just updated their cart in the background via an event, so in either case you probably wouldn't want a (long) cache. There are other tradeoffs with CQRS. For instance you might have a separate read store that's optimized for querying, and is updated from the transactional store. This works fine in typical CQRS scenarios but in your case you might have to block on the write to the cart until the change was propagated to the read store so that your subsequent query of the cart could complete, resulting in a somewhat longer overall response time. Probably a minor tradeoff, but still one to keep in mind. HTH. |
Beta Was this translation helpful? Give feedback.
-
For thousands of baskets when an item goes out of stock (or changes price, or has other changes), yes, I would update them all, but not in a single update statement or transaction. But rather as a sequence of events and event handlers, so that it would scale and I could do additional work (notifications, etc.) as part of the update. Yeah, I'd probably avoid sending a 2xx response (success) but then saying the content is out of date. In HTTP you can use a LastModified value to indicate how old the data is, but this is different from saying the content wasn't modified, but needs to be. Which is just kind of weird to me. I'd either update the cart when the product is out of stock (and again when it's back in stock) or do the update "just in time" as part of the query, as you originally proposed. |
Beta Was this translation helpful? Give feedback.
-
So typically we have HTTP GET and POST methods, GET methods would call Queries and POST would call commands. This keeps it nice and clean, but we have some situations where when loading in the data we need to validate the data and sometimes perform writes back to the database.
A good example of this is when we perform a query to get the active shopping basket, if the stock is no longer available we will remove the item from their basket, recalculate totals and return a message.
If modifying the state isn't allowed in a read, how would you do this?
Beta Was this translation helpful? Give feedback.
All reactions