0

I always think about this scenario where we need to perform a task conditionally and the task requires calling another microservice. What I am not able to understand is which microservice's responsibility is to evaluate the condition?

Let us take an example:
There is a dedicated inventory microservice. The system has certain conditions that decide whether inventory is applicable to a product or not. The conditions look like:

  1. The inventory is not applicable to the whole system.
  2. The inventory is not applicable to a particular sales channel like the app.
  3. The inventory is not applicable to a particular product. (Like services, non-tangible products).

The services that require inventory information may be, for example,

  • Shopping Cart microservice requiring services of the Inventory microservice for reservations
  • Catalog microservice requiring in-stock or out-of-stock status of the products
  • Order microservice needs to decrement the stock using the Inventory microservice

The question is, what among the below is a better design solution?

  1. Every microservice evaluates all the conditions and decides whether it needs to hit the inventory microservice or not, thereby saving unnecessary calls to inventory microservice.
  2. Every microservice hits the inventory microservice and the inventory microservice will decide whether to perform the operation or skip it depending on the conditions. This allows coding the "conditions evaluation" at a single place and cleaner code.
1
  • 1
    You already listed the pros and cons of the two approaches. Which one is more suitable for your case depends on the weights you assign to these pros and cons. As a general rule, optimization is often over-emphasized. Cleanliness and maintainability of code is actually more important when you start, and optimization should be done when you have measured the system and found its performance lacking. Commented Jun 26, 2020 at 11:52

1 Answer 1

2

This is a tricky one.

Before we jump into the details, just a small remark on your post itself:
The title of your question has already suggested a direction or your favor. The same would be true if you would name it like this: Microservices Guarded Endpoint Design. It seems like you have already made the decision just looking for justification. But this is just an observation, not a criticism.

Conditional Call or Guarded Execution

I think this question is applicable even on the method level. There might be different concerns if you talk about functions or microservices. But I think we can leave the microservices out from this question right now.

Whose responsibility is to prevent execution if some precondition fails?

  • Caller
    • It has the information to determine whether or not the execution is "safe"
    • The caller knows the preconditions of the callee (that can be an abstraction leaking as well)
    • It is responsible to gain exclusive access to the callee
    • The caller can decide that calling the callee can be an expensive operation (which may or may not succeeded)
    • etc.
  • Callee
    • It can not trust the caller (it does not have any guarantee that the caller has performed some preliminary check)
    • The guarding expression is closely related to the internal state
    • There are multiple different callers, so it is easier to have the condition check in a single place and new consumers should not need to implement that
    • Double-checking (making sure that what was true at the time when the caller has made the call it is true now as well)
    • etc.

I think based on these concerns you should be able to decide which would fit better for your use case.

1
  • @rohanagarwal Thanks for the edit suggestions. Commented Jul 7, 2020 at 9:59

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.