5

How does one service get the data from another service? I will give few examples:

1) Let's say we have two services which need to share the data: User Service and Order Service. Order Service pretty much will want to get some data User Service's database has like address, bonus points to cut the price, but all Order Service receives about a user is its userId, it doesn't have a direct access to the User DB.

2) An app has a user balance system with some internal coins used as base currency. The app provides different kind of services to buy which user can spend those internal coins for. The service responsible for fulfilling user's request should be somehow able to tell User Service or Balance Service (if it was decided to split balance from users to a different service) to reduce its balance depending on how much it costed or check the balance and then return a error if it's insufficient.

3) An app from #2 situation doesn't have predetermined price anymore, tasks got so complicated that now we need to run Analyze Service and now the task will go to that service to determinate the price of a task, what service should handle the task and only then the service which is able to fulfill user's request will do it.

So, I will give my thoughts about these after reading numerous articles about microservice architecture:

1) I see few ways to do it:

  • direct synchronous HTTP request from one service to another to get the necessary data (slow, most importantly services are now coupled and I loose benefits of microservice architecture)
  • client app has all necessary data in its global store (if it's a SPA app e.g.) and will just send them in the request (but we still need a mean to check if the data we got is valid...)
  • saving necessary data in JWT (weird..?)

2) I guess here is a good example where message brokers come in handy. I could send a message about the task being done with its price and userId to User Service or Balance Service and callback will reduce user's balance.

3) Message broker again. Analyze Service sends a message, bound performing task service will start doing a task after analyze is finished, which task service will do that depends on the queue Analyze Service will send a message in.

I'm not sure about any of solutions here so here is my question. What are common ways to deal with those kind of problems?

1
  • Wouldn't bonus points be stored in the bonus service?
    – user253751
    Jan 6, 2020 at 12:04

3 Answers 3

5

Service dependencies (and losing track thereof) are not uncommon with a microservice architecture. It's also expected that services have local data and this data can be keyed with a primary ID from another service. For example, some services are going to have some data attached to a user ID like you observed.

You should look at whether or not you have drawn your domain boundaries correctly and where they are over- or undersized (or need to be co-located in the same service)

You are correct that it's not good to have the knowledge how to get a particular object from another service in a service. In the case of a user service, you might have to accept that such a service will likely be needed as the need for user data might be frequent. In this case, you might want to create a layer or directed graph model (everyone may use the user service, user service may not use order service...)

There is also the orchestrator model. In that model, the application or an orchestrator service pulls all the needed data together and then hands if off for processing. So you would read from product, user, bonus-point etc. and then pass all of that into order service as data. This reduces the number of locations where the knowledge how to retrieve this data exists.

Side effects (like crediting bonus points) benefit from an asynchronous message passing mechanism. Crediting bonus points does not block order processing and order processing does not need to wait for bonus points to be credited. As long as bonus points are credited eventually, you are fine. The message passing subsystem can buffer messages if that service is down and you again remove the knowledge where that service is located and how it operates from the caller.

1

This post outlines a few approaches to share the data with their pros and cons.

In particular, one approach that looks pretty appealing but wouldn't necessarily be thought of by a developer coming from a monolith background is what the author calles "selective replication":

The developers of the User Service know that other services might need to know how many points a user has, so whenever the number of points updates they will send a message through the queue telling the other services how many points the user has.

When an order is going to be placed the price is computed with the points that are kept in theOrder Service database. You could have complex logic here like the Order Service calculating an estimated price, sending a message through the queue to acquire a "lock" on those points (the User Service manages the locks for it's own data), and then showing an exact price on the confirmation/payment page after it knows if the lock succeeded.

This approach will decouple your services, allow you to deploy/version independently, and enable services to work/be tested in a vacuum if needed, but it should probably only be used if your system actually needs microservices since it has a lot of overhead:

  • You either have to invalidate the caches and send periodic updates or you need some kind of synchronization job to run every once in a while.

  • You'll have to decide what to do if you get no response to your lock request (e.g. the User Service is down). Maybe you show the customer both prices and ask them what to do in case it turns out those points don't exist anymore, or maybe something else, but it's a condos decision you have to make (note that you basically had to make it with other approaches as well, but the bad default there was that you don't catch the error and your whole purchase request fails).

0

I think most of your solutions for 2nd and 3rd problem will work. There is not much bad in accessing a service with a HTTP request. Also, you could think about selection replication of necessary data and designing a loose-coupling services.

1
  • If might help the OP more if you elaborated on the pros and cons of each approach
    – Martin K
    Jan 8, 2020 at 16:51

Your Answer

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

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