Architecting basket in high scale distributed application
https://softwareengineering.stackexchange.com/questions/421146
-
21-03-2021 - |
Question
I'm designing an e-commerce application. Main flow is pretty straightforward: customer add items to basket, checkouts the basket (place an order) and waits for delivery.
There are following requirements:
- basket is kept on backend
- system should handle +5M baskets/orders per day
I know there is no single answer, but I'm looking for some comments/inspirations on how to design the basket & order module(s). I see following options:
basket
andorder
are separate services, andbasket
sends toorder
anID
of abasket
to checkout, thenorders
callsbasket
for a basket details
1A) API call based communication
1B) async message based communication
basket
andorder
are separate services, andbasket
sends toorder
a fullbasket
details
2A) API call based communication
2B) async message based communication
basket
andorder
are the same service, and checked-outbasket
becomes anorder
(it is same entity, just presented to user as basket or order, depending on it's state)
Solution
All three make sense. However:
The third one may be a valid option for a small application, but if the system grows, you'll tend to separate those services, given that their logic is completely separate: you don't need to know how to add products to a basket in order to order, and you don't need to know how to check for credit card number in order to manipulate the basket. So maybe not a good idea to use the third approach in your case.
(The first option creates a circular dependency between the services. This may not be a technical problem by itself, especially with a message bus (but even with API calls, it doesn't either), but it may be strange to reason about in some situations.)
The choice between API calls vs. a message bus depends a lot on your skills (and the skills of your team). API calls tend to be simpler to reason about, especially in problematic situations. Imagine that the basket service sends a message that the order service should process. A network issue delays the message. After some time, the basket service sends the message again. Immediately after that, the network is up to normal, and both messages are delivered to the order service. What happens? Or here's another situation. The original message is delivered and processed, but the acknowledgement never arrives.
If you had prior experience with a message bus (especially the edge cases where something goes wrong, MQS nodes fail, etc.), then go for it. If not, plain API calls may be a better alternative: you'll have the exact same problems with API calls too, but they usually tend to be simpler to reason about.