Search code examples
dependenciesmicroservicescomposition

Designing Microservice dependencies properly with related data


This is a highly theoretical question and focuses largely on me not completely grasping design principles behind related data in microservices and responsibility of obtaining related data.

The basic gist of my data could be exampled as follows (each service also hosts data named after the service in a DB which i will hide for simplicity):

I have an API Gateway routing /api/* requests to their proper services and handling authentication. I have a species-service, the species has a GUID PK and a name. I have a zoo-service, the zoo has a GUID PK and a name. I have an animal-service, an animal has a GUID PK, a species FK and a zoo FK and a name.

Following scenarios have to happen:

  1. I want to retrieve all animals in a zoo.
  2. I want to retrieve all animals of a species.
  3. I want to retrieve a single animal.

This is my current implementation (which I think may be flawed):

  1. The API Gateway recieves a GET request to /api/zoo/{zooId}/animals and requests the zoo-service to compose the data. The zoo-service requests all animals, grabs their species ID's and sorts them by species. If the species service does not respond they are only sorted by species ID's, but the species has no name.
  2. The API Gateway recieves a GET request to /api/species/{speciesID}/animals and requests the species service to compose the data. The species-service requests all animals and displays returns them.
  3. The API Gateway recieves a GET request to /api/animal/{animalID} and requests the animal-service to retrieve an animal. The returned data only contains the zoo ID and species ID.

I have the following two questions:

  1. In the given example, does the dependency of microservices seem reasonable? I am trying to handle a non-responsive service as good as possible in the service that depends on it.
  2. In the third scenario, who would be responsible for retrieving the data of an animals species and zoo? (I'd guess you would want as exact relevant data as possible for the entity you are requesting, so delivering the zoo name and species name would be good) The Frontend, API Gateway or the animal-service?

Solution

  • This decomposition looks like taking a relational DB schema and assigning each table to a different microservice. This decomposition takes all the coupling of a monolith and combines it with all the complexity of microservices, which means that you get very few of the benefits of either.

    An alternative decomposition focuses on the functionality: what operations are being exposed and how are they related (and what sort of consistency/independence relations should hold between the operations). If there's a strong consistency requirement between two operations, that's a strong sign that those two operations belong in the same microservice (doing that doesn't guarantee consistency, but not doing that dramatically increases the effort of ensuring consistency without giving the benefits of separate microservices (beyond, perhaps, having the ability to say "we have more microservices than we need!", if that's the sort of thing that gives one satisfaction)).

    So assuming we have an "add animal A with species S to zoo Z" operation, the question is then whether we want a guarantee that any subsequent request for all the animals in Z, all the animals of S, or the specific animal A sees the result of that operation. If the answer is yes, then those four operations probably "want" to be in the same microservice and the implementations of those operations are going to be coupled as a consequence. If the answer is no, then it's likely that eventual consistency with some liveness guarantee is acceptable, in which case (barring the presence of some other consistency relationship) put the operations into separate microservices and patterns like CQRS are possible.

    If doing CQRS, the service providing the "get all animals in the zoo" operation could then have its own view of what animals there are and their respective species. It then doesn't depend on the animals/species services being available: those being down/unable to talk to this service (which could happen because one service changed something, it should be noted) simply means that the view is out of date. Eventually, communication will be re-established and the operation will return updated data.