I'm a little confused about the flow in a system using domain events to build the read model. Particularly, how do we deal with the fact that the user expects data (and its view) to change when they complete a command, but due to our system architecture (non-blocking calls to publish events) the actual database might not change before the page is reloaded?
I'm hoping to move the design of one of our systems more inline with CQRS using events and a service bus.
Let's say my flow goes as such:
User clicks button in View to perform Task of removing Payment Method from their Account.
Controller calls PaymentMethodRemovalService, passing it accountId & paymentMethodId.
Controller uses AccountRepository to retrieve Account and calls account.RemovePaymentMethod(id)
Account validates that operation can occur and publishes event PaymentMethodRemovedMessage(accountId, paymentMethodId)
Because event publishing is asynchronous, we now have to return from service and return view from the controller - but our actual data isn't updated yet!
A handler, IHandle< PaymentMethodRemovedMessage >, hears the event and removes the actual row from the DB
So, what's a guy to do?
I could simply, say, remove the div that was displaying the payment method. This may work in an AJAX scenario, but what if I'm using Post-Redirect-Get to support non-JavaScript clients. Then I will be firing my Get and reading the data from the Query side of things, potentially before it's updated.
Do I just show a notification saying their request to remove the payment method has been submitted? (which doesn't seem to friendly, makes sense for submitting an order, but not for, say, changing an address).
Is there a way to reconcile implementing changes as decoupled asynchronous events and showing the user data that reflects their current change?
EDIT: My question is quite similar to CQRS, DDD synching reporting database I have to say, the answer given there and also alluded to here, has a bit of a smell to it - wrangling the UI to show an update that's out of band with the read DB, so to speak. I was hoping for something a little cleaner.
CQRS is implemented by a separation of responsibilities between commands and queries, and event sourcing is implemented by using the sequence of events to track changes in data.
CQRS allows you to define commands with enough granularity to minimize merge conflicts at the domain level (any conflicts that do arise can be merged by the command), even when updating what appears to be the same type of data.
CQRS separates reads and writes into different models, using commands to update data, and queries to read data. Commands should be task-based, rather than data centric. ("Book hotel room", not "set ReservationStatus to Reserved").
Read Models are about Queries This is where read models come in. A read model is a model specialized for reads, that is, queries. It takes events produced by the domain and uses them to build and maintain a model that is suitable for answering the client's queries.
If you are locked into the Request/Response model you could adopt a Correlated Request/Response pattern. For specifics, check out the Async Pages sample in the NSB download. This demonstrates Request/Response in an ASP.NET setting. There are some ASP.NET MVC examples out there if that is more your thing.
When you introduce asynchronous processing you are accepting that the data will be stale. One can argue that the moment you query the DB the data is already old(network latency, rendering time etc.). Since the data is already old, we must ask how old is good enough?
One more thing to consider is that your processing is a bit out of order. Step 3 should be validating the command prior to sending it to the server and then steps 3, 4 would come after 6. The database should only be updated if the command is valid and the event should only be published if the database is successfully updated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With