-->

Implementing a Saga/Process Manager in a CQRS http

2019-05-11 04:34发布

问题:

Following this example: https://msdn.microsoft.com/en-us/library/jj591569.aspx (Figure 3)

How it fits in a http application?

The user should perform a http request to the PlaceOrderController, which will send a PlaceOrderCommand, but how would the Order Process Manager answers the "9. Order Confirmed" to the user? How is the controller aware of that, in order to return this info to the user?

Thanks

回答1:

You simply don't answer "Order Confirmed" immediately. Take a look at how Amazon and other shopping sites do it: Upon Order submission, you just receive an "Order Accepted confirmation (e.g., HTTP Code 202 Accepted). When the actual order has been handled by the order process manager, an "Order Confirmed" notification on a separate message/channel (e.g., email) is sent to the user.



回答2:

@Hippoom points you to the right direction.

CQRS Journey (what are you reading) says:

The team later replaced this mechanism for checking whether the system saves the order with an implementation of the Post-Redirect-Get pattern. The following code sample shows the new version of the StartRegistration action method. For more information about the Post-Redirect-Get pattern see the article Post/Redirect/Get on Wikipedia.

[HttpPost]
public ActionResult StartRegistration(string conferenceCode,
OrderViewModel contentModel)
{
...
this.commandBus.Send(command);
return RedirectToAction(
"SpecifyRegistrantDetails",
new { conferenceCode = conferenceCode, orderId = command.Id });
}

The action method now redirects to the SpecifyRegistrantDetails view immediately after it sends the command. The following code sample shows how the SpecifyRegistrantDetails action polls for the order in the repository before returning a view.

[HttpGet]
public ActionResult SpecifyRegistrantDetails(string conferenceCode, Guid orderId)
{
var draftOrder = this.WaitUntilUpdated(orderId);
...
}

The advantages of this second approach, using the Post-Redirect-Get pattern instead of in the StartRegistration post action are that it works better with the browser’s forward and back navigation buttons, and that it gives

Here we are talking about eventual consistency of milliseconds or a few seconds in the worst case. So a P-R-G pattern fits perfect.

Anyway, here and here there you can read articles about eventualy consistency UI than can help you.

POST COMMENT EDIT:

Here Udi Dahan says:

When should you avoid CQRS?

The answer is most of the time.

Here’s the strongest indication I can give you to know that you’re doing CQRS correctly: Your aggregate roots are sagas

So, I think your problem is not discover how CQRS works for HTTP application. Your problem is that with the process and use cases about you are questioning you should avoid CQRS.



回答3:

Your Web/REST api is independent of your domain model but maps to it based on your use cases and user agent needs. One way to go is the submit a "job" and then poll the job for progress. There are many tradeoffs to consider. For example depending on your infrastructure sending a notification is probably the best way to go. If you want REST/HTTP you can try this:

User Agent:

POST /jobs/registrations
..content..

Origin Server:

HTTP/1.1 303 See Other
Location /jobs/registration/<some-job-id>

User Agent:

GET /jobs/registration/<some-job-id>
..content with job status..