3

I have two Microservices A and B.

  • B Microservice has a large set of an entity called User.
  • A Microservice stores the User entity in its own DB if User is configured by an agent. There is no flag available in Microservice B's DB to find if the User is configured.

I want to find all the list of all unconfigured user by page (Set(B)-Set(A)).

How should I go about querying if User data is too large in B Microservice?

  • Could you clarify why there is no such flag in the database B? Wouldn't adding the flag solve the problem? – COME FROM Dec 7 '18 at 10:17
  • If you are using .net, then try SignalR. I dont know if SignalR is available for other platforms. – Yawar Murtaza Dec 9 '18 at 19:53
  • @COMEFROM the schema with Microservice B's DB is fixed and there is no permission to edit the schema. Microservice B has only read permission on the database. – Puneeth mypadi Dec 10 '18 at 11:04
0

You can precalculate your aggragate before querying it by either emitting events or using active record. It will create easy to read aggragate - although you need to take care of updates of your base entities. That's an expedient solution.

However, in your case it looks like you need to step back and rethink your design. Might be a case that your microservices or tables are split suboptimally.

0

There is no good way to do this. Because your data is split across multiple microservices, you need to join this data manually. So there needs to be some piece of code like:

def find_unconfigured_users():
  for user in B.all_users():
    if A.has_configured_user(user):
      yield user

This is going to be tedious and slow, but because you are using microservices you don't have any reasonable choice. (The unreasonable choice would be to access B's data directly, without going through the microservice interface.)

Where this functionality should live depends … possibly, this should be part of the Microservice A itself, i.e. part of the service that deals with configured users.

When data is split like this over multiple microservices this might be a necessary evil, or could be an indication of a deeper problem. Domain-Driven Design has the concept of a bounded context – a self-contained part of the problem domain your software system is trying to solve. One bounded context should not be split across multiple microservices!

You might want to check which bounded context which aspects of a User belongs to. Why is there a need to deal with configured and unconfigured users, and why is that distinct from users in general? It is legitimate if different bounded contexts have different but related concepts of a “User”, but you have to be clear how they relate. Here, it seems like one User entity is effectively shared across different contexts, and therefore causing problems. Possibly, the solution could be to include the configuredness of a user into the main User context (B).

“The schema is fixed” is not necessarily a good reason to avoid doing this, but perhaps cannot be influenced by you. No technological solution will be able to solve organizational dysfunction – especially not microservices. You'll then have to fall back to tediously checking every user, as in the code snippet above.

  • We do not have influence on B's schema. Currently we are pursuing the same strategy which you have mentioned. The logic to check unconfigured users currently lives in Microservice B as data from Microservice A is always less than that in B so transmission of data from A to B is much faster than B ** to **A. The thing is when the data in Microservice A becomes too large, the application would timeout. – Puneeth mypadi Dec 26 '18 at 13:18
  • 1
    @Puneethmypadi If speed is a problem you may be able to cache the data, though this means the data may no longer be up to date. I don't think there's any good solution to your problem, only workarounds. – amon Dec 28 '18 at 11:37
0

It is ok (and desirable) to have properties of an entity, like User, stored in different microservices. There is no need for microservice A to store all the properties of user in microservice B (Name, Phone, email, etc) if A only cares about IsConfiguredByAgent and other things.

The problem in your design is that you should not have to query Service B from Service A in order to know the users that are not configured by an agent. In order to do that, you need the full set of users also in Service A. So, both Service A and Service B have the full list of User Ids, but they store different properties against them.

You do need one Service only to allow creating and removing users. Then this service can publish a UserCreatedEvent or UserRemovedEvent carrying the UserId and other services can listen to these events to update their internal list of users.

  • Microservice A only stores the primary keys of users in Microservice B. To find unconfigured users anyway we need to know which users are configured so need to be queried from *Microservice A – Puneeth mypadi Jan 9 at 13:12
  • 1
    Then I would recommend to redesign the Microservices so that they always know everything they need to know to perform their duties. Microservices calling each other is an antipattern. It goes against the concept of "being autonomous" as they cannot be autonomous if they need other microservices to be running all the time and providing specific features for them to do their duties. If you don't know how to redesign them so they are autonomous, merge them. You will safe yourself a lot of troubles, coupling and performance issues. – Francesc Castells Jan 9 at 19:27

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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