4

My new team where I work are currently discussing how we go about changing our current old monolithic applications to go down the route of microservices. We are still at the early discussion and proof of concept phase.

The first proof of concept we are trying out, at a high level, is to mimik a customer adding something to their basket, and what that would entail in the new architecture.

We currently have the following:

POC Archtiecture

What is happening here is as follows:

  1. Customer hits "Add to basket" button in browser which sends the POST request to the API Gateway
  2. API Gateway acts as a pass-through, sending an "Add To Basket" request to Rabbit MQ
  3. Basket Saga picks this request up, starts a new saga
  4. Basket Saga adds "Add Item to Basket" and "Reserve Item" requests to Rabbit MQ
  5. Stock Service picks up "Reserve Item" request and reserves it
  6. Stock Service adds an "Item Reserved" event to Rabbit MQ
  7. Basket Service picks up "Add Item To Basket" request and adds it
  8. Basket Service adds an "Item Added" event to Rabbit MQ
  9. Basket Saga picks up both the "Item Reserved" and "Item Added" events
  10. Basket Saga posts a "Add To Basket Complete" event to Rabbit MQ
  11. SignalR Host picks up the "Add To Basket Complete" event
  12. SignalR Host lets the browser know that the action has completed successfully

Now this is a very simple example just used to test the waters with this type of architecture.

Does this architecture seem sound enough? Or will it give long-term pain? There are obviously other options, like calling the microservices directly from the API Gateway amongst others.

Thoughts?

3
  • Here is a very similar example: medium.com/@wrong.about/… . Very relevant as well: medium.com/@wrong.about/… Nov 17, 2017 at 15:12
  • 1
    Seems fine, but the entire point of the MQ is to make things asynchronous. Having the steps be completely serial is robbing yourself of much of the benefits.
    – Telastyn
    Nov 17, 2017 at 15:37
  • The main work is done by the stock and basket service, and they both run in parallel. Nov 17, 2017 at 17:44

2 Answers 2

7

In theory its fine to have all these messages flying around but in practice each one requires a level of error handling over and above a synchronous API call. It doesn't make sense to use them for fast calls within the same service.

First off. if you really are doing an e-commerce site where adding to basket requires a server call. Stop. It wont scale. do the whole thing client side. Check the stock levels when you come to fulfil the order at the warehouse.

Its even worse if every client has an open websockets connection. don't go there.

If its just an example, you can lose a few messages, just have the client send add to basket, process that in one service and send the response message back. Those internal messages might seem cool, but unless there is a real reason for them you are just making your life hard.

3
  • Good and pragmatic recommendation.
    – Andy
    Nov 18, 2017 at 8:37
  • "Check the stock levels when you come to fulfil the order at the warehouse." Are you suggesting to let the user make an order that can't be fulfilled?
    – Qwertie
    Dec 13, 2017 at 2:25
  • yes, you can always order more stock, or apologise and cancel the order.Its better than losing orders because your site is slow in a sale
    – Ewan
    Dec 13, 2017 at 6:54
2

I can't speak to your other workflows but what you have described here is a set of asynchronous remote procedure calls, coordinated by the Basket Saga service.

I would strongly recommend that you look at them that way and not, as implied here, with independent request and acknowledgement messages.

The reason is errors and timeouts. To keep the workflow logic tractable, for anything more than a trivial flow, you'll want to encapsulate the success, error and timeout paths. Under the covers you may run these as messages that share, say, request ids, but abstract this away from the workflow logic.

Keeping the async RPCs on a queue that you poll in a loop is a common way of implementing the workflow service.

If you do have workflows that include fire and forget notifications then absolutely use raw messages for those.

Also, if you combine your inbound and outbound gateways, you can run a similar loop to the Basket Saga service that just maintains async RPCs to the Basket Saga service.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.