Ich habe gerade die Spring Cloud Netflix- Dokumentation gelesen, als ich herausgefunden habe, wie eine Schnittstelle zwischen einem HTTP-Server und seinem Client gemeinsam genutzt werden kann. Sie verwenden dieses Beispiel für Microservices, obwohl es keinen Grund gibt, warum es nicht auf die generische HTTP-Kommunikation ausgedehnt werden kann:
// The shared interface, in a common library
public interface UserService {
@RequestMapping(method = GET, value = "/users/{id}")
User getUser(@PathVariable long id);
}
// The controller, on the server
@RestController
public class UserResource implements UserService {
}
// The same interface used for the client
@FeignClient("users")
public interface UserClient extends UserService {
}
Dies definiert eine Schnittstelle, die sowohl als Server (The Spring @RestController
verwandelt sie in einen HTTP-Server) als auch als Client (The Feign @FeignClient
richtet sie für die Verwendung als HTTP-Client ein) verwendet wird. Die Server- und Clientklassenimplementierungen können in separaten Projekten verwendet werden, verwenden jedoch dieselbe Schnittstelle, um sicherzustellen, dass die Typen übereinstimmen.
Unter das Beispiel stellen sie jedoch die folgende Einschränkung:
Hinweis: Es ist im Allgemeinen nicht ratsam, eine Schnittstelle zwischen einem Server und einem Client freizugeben. Es führt eine enge Kopplung ein und funktioniert auch in der aktuellen Form nicht mit Spring MVC (die Zuordnung von Methodenparametern wird nicht vererbt).
OK, es ist momentan nicht gut integriert ... aber dieser Teil kommt nach der Warnung vor dem Teilen von Code und der Einführung der Kopplung zwischen dem Server und dem Client, was sie für wichtiger halten. Warum halten sie es für eine so schlechte Idee, eine Schnittstelle auf diese Weise zu teilen?
Ohne sie verlieren Sie die Fähigkeit zu garantieren, dass Server und Client sich gegenseitig Daten senden, die beide verstehen können. Sie können dem einen, aber nicht dem anderen Feld ein Feld hinzufügen und die Nichtübereinstimmung nur bis zur Laufzeit feststellen. Meiner Meinung nach , ist es nicht die Einführung Kupplung, sondern lediglich enthüllt Kopplung , die bereits existiert. Ist die Notwendigkeit, Server vollständig unabhängig zu machen, größer als die Notwendigkeit, ihnen mitzuteilen, welche Arten von Daten sie erhalten werden?
quelle
Antworten:
Der in den Kommentaren angegebene Grund ist, dass Ihre Client-Plattform eng mit Ihrer Server-Plattform verbunden ist. Hier bedeutet dies, dass Ihr Client die Sprache / Plattform verwenden muss, die Sie auf dem Server verwenden, um den erwarteten Vertrag Ihres Servers zu verstehen. Beachten Sie, dass es einen Unterschied zwischen der Freigabe desselben Codes (ein Artefakt einer bestimmten Sprache / Plattform) und der Vereinbarung eines bestimmten Vertrags gibt.
Viele Projekte verwenden stattdessen Dokumentation für ihre Verträge. Beispielanfragen und -antworten in einem neutralen Format (z. B. JSON) über Standardprotokolle (z. B. REST). (Siehe z. B. Stripe-API-Dokumente .) Da es unpraktisch ist, einen Code-basierten Vertrag für jede mögliche Client-Plattform zu schreiben, die Sie möglicherweise verwenden oder zulassen möchten. Wieder andere verwenden API-Verwaltungstools, um neutrale Verträge zu definieren .
Ihr Beispiel für das Hinzufügen eines Felds ist ein separates Problem - ein Beispiel dafür, warum es wichtig ist, API-Verträge zu versionieren. Lassen Sie die Clients die Version verwenden, für die sie entwickelt wurden. Neben der alten gibt es eine abwärtskompatible neue API-Version. Der Client für die alte Version arbeitet so lange weiter, bis sein Team mit der Aktualisierung fertig ist oder bis Sie die alte Version zurückziehen (nach einer Verfalls- / Migrationsperiode). Siehe Parallele Änderung .
Das Befolgen der (impliziten Hinweise in der) Warnung hilft dem Client und dem Server, sich auf eine Weise und in Schritten zu entwickeln, die für jeden sinnvoll sind. Wenn Sie vernünftigerweise garantieren können, dass Ihr Server und Client immer dieselbe Sprache / Plattform verwenden UND sich im gleichen Tempo weiterentwickeln, ist die Verwendung eines sprach- und plattformspezifischen Code-Artefakts als Vertrag wahrscheinlich in Ordnung. Dies ist jedoch wahrscheinlich keine vernünftige Erwartung, insbesondere für Projekte, die auf Netflix OSS abzielen (etwas, das speziell auf Cloud-Skalierbarkeit und -Leistung mit all dieser erforderlichen Komplexität ausgerichtet ist).
quelle