Microservice Clients Circular Dependency

Viewed 846

In a Microservice architecture, using client packages to communicate between services, we ran into an issue where two client packages depend on each other, creating a circular dependency.

We are trying to figure out the best solution for this and I'm wondering if anyone would be able to help or point us in the right direction.

Here is the scenario:

  • Two services, Car and Insurance
  • Two client packages, CarClient and InsuranceClient.

Whenever any service needs to communicate with the Car service, it should use the CarClient package to do so. And whenever any service needs to communicate with the Insurance service, it should use the InsuranceClient package.

The CarClient package has a data transfer object (DTO) Car where one of its properties is insurance. The type for this property is a DTO available in the InsuranceClient package, CarInsurance.

The issue is when the CarInsurance DTO needs to access an enum available in the CarClient package, CarTypeEnum. Now we have the two packages depending on each other.

Microservice Clients Circular Dependency

Possible solutions I can think of:

  1. This is due to a bad design. Redesign the services and packages to prevent this circular dependency.
  2. Move the enums into separate packages, therefore, both clients can depend on these packages but the clients wont't depend on each other.

Any help is appreciated.

3 Answers

You shouldn't be sharing any code between services since that defeats the whole purpose of them being 100% independent.

In a MS architecture a CarDTO would only have properties related to a car. If you want information about insurance that would be a separate call to the insurance service to get an InsuranceDTO that has only insurance properties.

When calling either service you would use some key to tie it all together. I.e. you would call the car service with a customerId that you got from the customer service and your CarDTO would have a carId, then you can call the insurance service with customerId/carId to get the InsuranceDTO.

I read the long conversation in comments of previous answer and I would like to make an addition which is kind of supporting the idea of "just duplicate them on each repo".

If you design your services based on the idea of DDD(domain driven design) you may be aware that the same concept/entity could mean different things in different domains.

That means "insurance" inside the CarService may have -depending on the domain/requirements- quite some different attributes then the one in InsuranceService. That is why the insurance concept in CarService should have its own dto which should be totally free from InsuranceService's insurance definition.

You could just not use the CarTypeEnum in your Insurance service. Just use a CarId. When you need to know the type, just ask the car service for that information.

Related