it-swarm.com.de

Gemeinsame Nutzung von DTO-Objekten zwischen Microservices

TL; DR - Ist es in Ordnung, eine POJO-Bibliothek zwischen Diensten zu teilen?

Im Allgemeinen möchten wir die Freigabe zwischen Diensten nach Möglichkeit streng auf keine beschränken. Es gab einige Debatten darüber, ob der Dienst, der Daten gemeinsam nutzt, eine Client-Bibliothek für Clients bereitstellen soll. Die Client-Bibliothek ist für einen Client des Dienstes im Allgemeinen optional und kann die API nach Belieben verwenden, unabhängig davon, ob die Client-Bibliothek oder eine alternative Sprache verwendet und die allgemeinen Aspekte der Bibliothek und dergleichen verwendet werden sollen.

In meinem Fall - Ich betrachte einen Dienst, der ein Datenobjekt erstellt. Nehmen wir an, dieses Objekt ist ein PET. Es ist NICHT die Datenbankeinheit, sondern ausschließlich ein POJO, das implizit die zugrunde liegenden Daten darstellt. Dieses POJO hat die API definiert. Angenommen: Haustier - Alter, Gewicht, Name, Besitzer, Adresse, Art usw.

Service 1 - PetKeeper: Es generiert aus irgendeinem Grund ein Haustier und speichert alle Daten. Es muss auf diesen Service verweisen, um das Haustier zu erhalten, oder Änderungen am Haustier vornehmen, sagen wir, der Name ändert sich oder Die Adressänderung muss über einen API-Aufruf an diesen Dienst erfolgen.

Service 2 - PetAccessor: Dieser Service sammelt die Haustiere und führt Validierungsprüfungen durch

Service 3,4 - Weitere Zwischen-Service-Anrufe

Service 5 - Benutzerschnittstelle

Diese sind sehr willkürlich, aber der Punkt ist einfach. Die Benutzeroberfläche oder ein benutzerbezogener Dienst möchte dieses "PET" -Objekt auf irgendeine Weise präsentieren. Es muss über eine API einen Dienst aufrufen, der einen Dienst aufruft, der einen Dienst aufruft usw., bis es den Dienst erreicht, der die erforderlichen Informationen sammelt und das Relay zurück startet. Schließlich muss der UI-Dienst das Objekt PET] anzeigen.

Dies ist ziemlich häufig - aber mit unserer absoluten Mentalität haben wir das Objekt PET== in jedem Dienst dupliziert. DRY (wiederholen Sie sich nicht)) gilt nur für Code INNERHALB eines Dienstes und gilt nicht für alle Dienste, aber der Punkt ist immer noch vorhanden. Was ist, wenn wir ein Feld hinzufügen ... müssen wir jeweils 5 Dienste des POJO ändern.

--OR-- Wir können eine Pet-Objects-Bibliothek bereitstellen, die einige der Pojos aus der API enthält, und jeder Dienst kann die Bibliothek importieren/von ihr abhängig machen. Es besteht keine Abhängigkeit von den Diensten selbst, sondern nur von der allgemeinen Bibliothek. Ich mag diese Idee, damit jeder Dienst den gleichen Objekttyp hat und Aktualisierungen einfacher sind. Aber ich mache mir Sorgen um Gott-Objekte.

Was sind die Vor- und Nachteile - was ist das beste Design? Was haben Sie getan, um Daten zwischen Diensten zu übertragen, um die Wiederholung derselben POJO-Klassen zu minimieren und gleichzeitig die Entkopplung zu gewährleisten?

15
Aerith

Was ist das beste Design?

Sie können dasselbe Pet [~ # ~] dto [~ # ~] Objekt unter den Backend-Diensten (die die typische Geschäftslogik verarbeiten) wiederverwenden, aber wenn es darum geht In der Präsentationsebene (Benutzeroberfläche) empfiehlt es sich im Allgemeinen, eine FormBean (eine andere Bean mit hinzugefügten Feldern für die Präsentationslogik) zu verwenden, damit eine klare Trennung erfolgt zwischen Präsentationslogik und Geschäftslogik.

Dies ist erforderlich, da Dienste wiederverwendbar sein sollten und ein einzelner Dienst von mehreren/unterschiedlichen Endpunkten verfügbar gemacht/wiederverwendet werden kann (wie Frontend oder ein anderer Webservice usw.) und jeder dieser Endpunkte Möglicherweise sind zusätzliche Felder erforderlich, die von den jeweiligen Controllern oder Layern (wie Adaptern) über den Diensten ausgefüllt werden.

Was haben Sie getan, um Daten zwischen Diensten zu übertragen, um die Wiederholung derselben POJO-Klassen zu minimieren und gleichzeitig die Entkopplung zu gewährleisten?

Wenn Sie eine einzelne Bean zwischen Geschäfts- und Webebenen verwenden, koppeln Sie die Präsentationslogik eng mit der Geschäftslogik, was keine gute Praxis ist, und Sie werden am Ende die Dienste für eine Anforderung im Frontend ändern (wie zum Beispiel ein anderes Datumsformat, das in der Benutzeroberfläche angezeigt wird). Um diesen Prozess des Auffüllens/Kopierens der Daten über die Beans (wie DTO zu FormBean oder Viceversa) durchzuführen, können Sie auch Bibliotheken wie ApacheBeanUtils.copyProperties() oder Dozer um den Boilerplate-Code zu vermeiden.

5
developer

Wenn das DTO in allen Mikrodiensten dieselbe Geschäftseinheit darstellt, sollte es nur eine Klasse geben, die von den Diensten gemeinsam genutzt wird. Es ist (fast) nie richtig, doppelten Code für dasselbe Objekt zu haben.

4
Jim Garrison

So wie ich es jetzt vorhabe, verpackt jeder Dienst nur DTOs und legt sie als jar lib in Nexus ab. Wenn andere Dienste diese benötigen, erhalten sie diese DTO-Bibliothek (en) als Abhängigkeit in manve/gradle. Wenn eine neue DTO-Version für einen Dienst veröffentlicht wird, ist dies in Ordnung, solange gleichzeitig auch die alte Version unterstützt wird. Brechen Sie also nicht die Abwärtskompatibilität, die Versionierung usw. ab. Dies ist also ein Bereich von Backend zu Backend. m eine Abhängigkeit vom Kreislauf zu vermeiden, ist es besser, den Service von der dto-Verpackung zu trennen.

Schauen Sie sich jetzt Backend-to-Frontend an und umgekehrt Ich bin mit früheren Kommentaren nicht einverstanden, dass die Benutzeroberfläche als Präsentationsschicht anders ist. IT IS NOT !!! UI ist für mich nur ein weiterer Microservice, der auch Ereignisse konsumiert und produziert.

Backend-zu-Frontend-Richtung Ich konvertiere POJO (dtos) in TypeScript-Schnittstellen und packe sie in NPM und lade sie auch in Nexus. Das auf UI-Knotenjs basierende Projekt verwendet diese dann und verwendet sie. Dies ist Weg Service zur Benutzeroberfläche.

Richtung von Frontend zu Backend Damit die Benutzeroberfläche Ereignisse auf Serviceebene bedient, konvertiere ich TypeScript-Schnittstellen und konvertiere sie in POJOs (dtos), verpacke sie als JAR und lade sie in Form von JAR in Nexus (oder ein Repo) hoch von Backend-Diensten verbraucht.

Diese Prozesse können leicht von CI-Prozessen (Travis, Gitlab CI usw.) gehandhabt werden.

Alle Kommentare zu diesem Ansatz sind willkommen.

1
kensai