mardi 31 octobre 2023

circular dependencies when trying to separate functionality (webservice sync)

I am contacting you today regarding a recent problem with circular dependencies. It's about a Spring boot application that accepts data via a Rest API and then forwards it to an internal Spring service. When a new vehicle is to be created, then first a CarDto is submitted via Rest. The controller uses a car mapper (Mapstruct) to create a car object from it and passes it to the CarService. However, the CarService cannot save the object immediately. First, the object is enriched with further information. This information comes from a web service. If an error occurs during the retrieval (e.g. because the manufacturer is not known to the web service), an exception is thrown and the CarService does not perform persistence. However, if the web service receives a result, it expands the object using the vehicle mapper (also a map construct) and returns the object to the service. The service can now save the object. For its functionality, however, the mapper absolutely needs access to the CarService to retrieve further information from the database in order to extend the Car object.

Now comes the difficult point: the information from the web service can change in principle. This means that the information in the database must be regularly compared with the web service. For this purpose, the following steps must be taken:

  • Pull all car objects from the database (due to the quantity with paging).
  • Synchronize objects with web service
  • Update objects in case of changes
  • then persist them again

Currently I have this functionality stuck in the VehicleService. To fetch the elements and save them, however, it needs the CarService (circular dependency). I could now put the sync function in the CarService, but then the question is when the translation from the Vehicle to the Car object should take place. If the translation should take place within the VehicleService, then I need the VehicleMapper in the VehicleServices. However, the VehicleMapper needs the CarService again. If I want to map the returns of the web service to a Car object in the VehicleService, I only need a DTO for the transfer of the information from the Car to the VehicleService. I don't really like that either.

I have hope that you guys have tips. Gladly also with the consequence eiens Refactorings.

For better illustration I have created a small class diagram. Please forgive me if not all characters fit perfectly - unfortunately I am not an uml expert.

https://i.stack.imgur.com/YRmdO.png

1 commentaire: