Je lisais la documentation de Spring Cloud Netflix lorsque j'ai découvert un moyen de partager une interface entre un serveur HTTP et son client. Ils utilisent cet exemple pour les microservices, bien qu'il n'y ait aucune raison pour qu'il ne puisse pas s'étendre à la communication HTTP générique:
// 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 {
}
Cela définit une interface qui est utilisée à la fois comme serveur (The Spring le @RestController
transforme en serveur HTTP) et comme client (The Feign la @FeignClient
configure pour une utilisation client HTTP). Les implémentations de classe serveur et client peuvent être utilisées dans des projets distincts mais utilisent toujours la même interface pour garantir la correspondance des types.
Cependant, sous l'exemple, ils ont mis la mise en garde suivante:
Remarque: Il n'est généralement pas conseillé de partager une interface entre un serveur et un client. Il introduit un couplage étroit et ne fonctionne pas réellement avec Spring MVC dans sa forme actuelle (le mappage des paramètres de méthode n'est pas hérité).
OK, donc ce n'est pas bien intégré en ce moment ... mais cette partie vient après l'avertissement contre le partage de code et l'introduction du couplage entre le serveur et le client, ce qu'ils pensent être plus important. Pourquoi pensent-ils que c'est une si mauvaise idée de partager une interface de cette façon?
Sans cela, vous perdez la possibilité de garantir que le serveur et le client s'envoient mutuellement des données qu'ils peuvent tous deux comprendre. Vous pouvez ajouter un champ à l'un mais pas à l'autre et découvrir uniquement la non-concordance jusqu'à l'exécution. À mon avis, il ne s'agit pas d' introduire un couplage, mais simplement de révéler un couplage qui existe déjà. La nécessité de rendre les serveurs complètement indépendants est-elle supérieure à la nécessité de leur faire savoir quels types de données ils recevront?
la source
Réponses:
La raison, comme indiqué dans les commentaires, est qu'il en résulte un couplage étroit de votre plate-forme client à votre plate-forme serveur. Ici, cela signifie que votre client doit utiliser la langue / la plate-forme que vous utilisez sur le serveur afin de comprendre le contrat attendu de votre serveur. Notez qu'il y a une différence entre partager le même code (un artefact d'une langue / plate-forme spécifique) et convenir d'un contrat spécifique.
De nombreux projets utilisent à la place de la documentation pour leurs contrats. Exemples de demandes et de réponses dans un format neutre (par exemple JSON) sur des protocoles standard (par exemple REST). (Voir la documentation de l'API Stripe , par exemple). Parce qu'il n'est pas pratique d'écrire un contrat basé sur du code pour chaque plateforme client possible que vous voudrez peut-être utiliser ou autoriser. D'autres encore utilisent des outils de gestion d'API pour définir des contrats neutres .
Votre exemple d'ajout d'un champ est une préoccupation distincte - un exemple de l'importance de la version des contrats d'API. Laissez les clients utiliser la version pour laquelle ils sont conçus. Une nouvelle version d'API incompatible en amont existe aux côtés de l'ancienne. Le client de l'ancienne version continue de fonctionner jusqu'à ce que son équipe se mette à le mettre à jour ou jusqu'à ce que vous retiriez l'ancienne version (après une période de dépréciation / migration). Voir Changement parallèle .
Suivre l'avertissement (conseils implicites dans) aide le client et le serveur à évoluer d'une manière et d'un rythme qui ont du sens pour chacun. Si vous pouvez raisonnablement garantir que votre serveur et votre client partageront toujours la même langue / plate-forme ET évolueront au même rythme, alors utiliser un artefact de code spécifique à la langue et à la plate-forme que votre contrat sera probablement correct. Cependant, ce n'est probablement pas une attente raisonnable, en particulier pour les projets ciblant Netflix OSS (quelque chose spécifiquement conçu pour l'évolutivité et les performances du cloud, avec toute cette complexité requise).
la source