-1

You have a set of microservices A, B, C that interact with microservice D for various reasons and one day you discover that sometimes one of the input fields of one of the REST Apis of D need to be potentially cleaned or transformed, by joining it with some other information. You have basically two choices:

  1. Implement a service E and write the logic in A,B,C that interacts with E before calling D
  2. Implement a specialized port in D and handle the mapping, cleaning and transformation there

The second approach seems superior in the sense that it provides less duplication and it is easier to test. Are there drawbacks that we don't see?

Dnomyar
  • 595
  • 4
  • 16
Edmondo1984
  • 17,841
  • 12
  • 55
  • 99

3 Answers3

1

From my point of view, the job of transforming the input parameters of the rest api of D has to be done by the driver adapter of D, i. e. by the rest controller, that takes the rest request and calls the application service of D.

choquero70
  • 3,332
  • 2
  • 24
  • 40
0

Sorry, no answers, just questions about the nature of those services:

  • Who owns this model transformation logic? Does it belong to D's business domain? Or is it supposed to address intricacies of the input provided by one of the clients?

  • When speaking about the model transformation, you are using the word "clean". Does it mean cleaning excessive information, or do you actually have to remove some sensitive details that shouldn't be there at all?

  • Also, what are its reasons for change? If the logic will have to change, will it have to change in parallel with D, the clients, or all of them?

Vladik
  • 168
  • 1
  • 7
  • Thanks for taking the time to answer: service D has an application service that takes as an input the address of a person, and one of the members of the address is the city. In A,B and C the address contains the city that corresponded to the address when your user signed-up for your service, but then the municipality could get aggregated with the one next door to save on administrative cost, and service D works on the address with "the municipality as of today". So you need to map between all-time municipalities and the one that are still valid. – Edmondo1984 Oct 22 '19 at 13:02
  • It sounds like the original address is the operational model for services A, B, C. The model of merged municipalities is not their concern. Having them call service E (option 1), would duplicate the knowledge that the service D works with merged municipalities. Another question: what do you mean by having a specialized port on D? One that will return the transformed model to the clients so it can be used for calling D's methods? Is there no way to encapsulate this translation and make it invisible for the clients? – Vladik Oct 22 '19 at 19:16
  • I mean that one obvious port to D takes the "current" municipality and one specialied port takes 'any municipality' and mapping to the current one. If I make it in the port (a specialized rest api) it will be transparent to clients – Edmondo1984 Oct 24 '19 at 09:17
-1

The problem you are facing could be solved with a little change in your architecture design, by applying dependency inversion principle.

Assuming that the principle is clearly understood, at an architecture level, instead of having multiple micro-services communicating through multiple APIs, you should break that direct dependency, and be able to avoid, as much as possible, to ask stuff to other micro-services.

You can do that implementing an event driven architecture: when something occurs in one service, that service publishes an event to a message broker (like RabbitMQ), and other interested services can subscribe to that event and do stuff with that information, like creating a local projection of the needed information to avoid query back.

If any micro-service knows everything it needs, you can avoid coupling and you can scale the ecosystem properly. Moreover, you simple cut that latency introduced by having those services communicating one with each other.

Good luck!

rastafermo
  • 358
  • 1
  • 3
  • 12
  • We already implement all that. My question was about trade off of multiple micro services implementing a similar anti corruption layer or exposing a specialised port for that purpose – Edmondo1984 Nov 16 '19 at 07:23
  • You said option 1 is "Implement a service E and write the logic in A,B,C that interacts with E before calling D", so you have direct interactions between those services, and that means that you are not using messages and a reactive event-driven architecture, so you actually didn't already implement what I was saying. The option 2 you proposed is basically the same: if you open a port in a service, it implies that someone has to use it, so once again you have direct communication between services. In one answer, you also refer to that port as "a specialized rest api". – rastafermo Nov 16 '19 at 12:37