Dans le monde dynamique des microservices, tout peut changer - n'importe quel composant peut être réécrit dans un autre langage en utilisant des cadres et une architecture différents. Seuls les contrats doivent rester inchangés, afin qu'il soit possible d'interagir avec le microservice de l'extérieur de façon permanente, indépendamment des métamorphoses internes. Et aujourd'hui, nous parlerons de notre problème de choix d'un format pour décrire les contrats et partager les artefacts trouvés.

Le message a été préparé par
Anna Melekhova et
Vladimir LapatinMicroservices. Lors du développement d'Acronis Cyber Cloud, nous avons réalisé que nous ne pouvions pas nous éloigner d'eux. Et la conception de microservices est impossible sans formaliser un contrat, qui est une interface de microservices.
Mais lorsqu'un produit contient plus d'un composant et que l'élaboration d'un contrat devient une activité régulière, vous commencez involontairement à penser à optimiser le processus. Il devient évident que l'interface (contrat) et l'implémentation (microservice) doivent correspondre, que les différents composants doivent faire les mêmes choses de la même manière, et que sans une adoption centralisée de toutes ces décisions, chaque équipe sera obligée de passer du temps à les obtenir encore et encore .
Disposition des microservices Amazon du tweet de Werner Vogelis, Amazon CTOQuel est le dilemme? De facto, les microservices interagissent de deux manières: HTTP Rest et gRPC de Google. Ne voulant pas s'impliquer dans la pile technologique de Google, nous avons choisi HTTP Rest. Les annotations aux contrats HTTP REST sont le plus souvent décrites dans l'un des deux formats: RAML et OAS, anciennement Swagger. Par conséquent, chaque équipe de développement est confrontée à la nécessité de choisir l'une des normes. Mais, il s'est avéré que faire ce choix peut être très difficile.
Pourquoi des annotations?
Une annotation est nécessaire pour qu'un utilisateur externe puisse facilement comprendre ce qui peut être fait avec votre service via son interface HTTP. Autrement dit, l'annotation doit contenir au moins une liste des ressources disponibles, leurs méthodes HTTP, les corps de la demande, une énumération des paramètres, une indication des en-têtes nécessaires et pris en charge, ainsi que des codes de retour et des formats de réponse. Un élément extrêmement important de l'annotation du contrat est leur description verbale («que se passe-t-il si vous ajoutez ce paramètre de requête à la demande?», «Dans quel cas le code 400 retournera-t-il?»)
Néanmoins, quand il s'agit de développer un grand nombre de microservices, je veux tirer un avantage supplémentaire des annotations écrites. Par exemple, basé sur RAML / Swagger, vous pouvez générer du code client et serveur dans un grand nombre de langages de programmation. Vous pouvez également recevoir automatiquement la documentation du microservice et la télécharger sur votre portail développeur :).
Un exemple de description de contrat structuréeLa pratique de tester les microservices sur la base des descriptions de contrat est moins courante. Si vous avez écrit une annotation et un composant, vous pouvez créer un autotest qui vérifie l'adéquation du service avec différents types de données d'entrée. Le service renvoie-t-il un code de réponse qui n'est pas décrit dans l'annotation? Sera-t-il capable de traiter correctement des données sciemment incorrectes?
De plus, l'implémentation de haute qualité non seulement des contrats eux-mêmes, mais également des outils de visualisation des annotations facilite le travail avec le microservice. Autrement dit, si l'architecte a décrit qualitativement le contrat, sur sa base, les concepteurs et les développeurs implémenteront le service dans d'autres produits sans frais supplémentaires.
Pour le fonctionnement d'outils supplémentaires, RAML et OAS ont la possibilité d'ajouter des métadonnées qui ne sont pas fournies par la norme (
par exemple, cela se fait dans OAS ).
En général, le champ de la créativité dans l'application des contrats de microservices est immense ... du moins théoriquement
Comparaison hérisson avec serpent
Actuellement, le domaine de développement prioritaire d'Acronis est le développement de la plate-forme Cyber Acronis. Acronis Cyber Platform - ce sont de nouveaux points d'intégration de services tiers avec Acronis Cyber Cloud et la partie agent. Bien que nos API internes décrites dans RAML nous convenaient, la nécessité de publier à nouveau l'API a soulevé la question du choix: quelle norme d'annotation est préférable d'utiliser pour notre travail?
Au départ, il semblait qu'il y avait deux solutions - il s'agissait des développements les plus courants de RAML et Swagger (ou OAS). Mais en fait, il s'est avéré que les alternatives ne sont pas au moins 2, mais 3 ou plus.
D'une part, il y a RAML - un langage puissant et efficace. Il implémente bien la hiérarchie et l'héritage, donc ce format convient mieux aux grandes entreprises qui ont besoin de nombreuses descriptions - c'est-à-dire, pas un seul produit, mais de nombreux microservices qui ont des parties communes de contrats - schémas d'authentification, mêmes types de données, corps d'erreur.
Mais le développeur RAML, Mulesoft, a rejoint le consortium Open API qui développe
Swagger . Par conséquent, RAML a suspendu son développement. Pour imaginer le format de l'événement, imaginez que les responsables des principaux composants Linux soient allés travailler chez Microsoft. Cette situation crée les conditions préalables à l'utilisation de Swagger, qui se développe dynamiquement et dans la dernière - troisième version - rattrape pratiquement RAML en termes de flexibilité et de fonctionnalité.
Sinon pour un mais ...
Il s'est avéré que tous les utilitaires open source n'ont pas été mis à jour vers la version OAS 3.0. Pour les microservices sur Go, le plus critique sera le manque d'adaptation du
go-swagger à la dernière version de la norme. Cependant, la différence entre Swagger 2 et Swagger 3 est
énorme . Par exemple, dans la troisième version, les développeurs:
- description améliorée des schémas d'authentification
- prise en charge complète du schéma JSON
- pompé la possibilité d'ajouter des exemples
La situation est drôle: lors du choix d'une norme, vous devez considérer RAML, Swagger 2 et Swagger 3 comme des alternatives distinctes. Cependant, seul Swagger 2 prend en charge correctement la boîte à outils OpenSource. RAML est très flexible ... et complexe, et Swagger 3 est mal pris en charge par la communauté, vous devez donc utiliser des outils propriétaires ou des solutions commerciales, qui sont généralement très chers.
Dans le même temps, s'il existe de nombreuses fonctionnalités intéressantes dans Swagger, telles que le portail prêt à l'emploi
editor.swagger.io , sur lequel vous pouvez télécharger l'annotation et obtenir sa visualisation avec une description détaillée, des liens et des liens, il n'y a pas une telle possibilité pour une RAML plus fondamentale et moins conviviale. Oui, vous pouvez rechercher quelque chose parmi les projets sur GitHub, y trouver un analogue et le déployer vous-même. Cependant, dans tous les cas, quelqu'un devra prendre en charge le portail, ce qui n'est pas si pratique pour une utilisation de base ou des besoins de test. De plus, le swagger est plus "sans principes", enfin, ou libéral - il peut être généré à partir de commentaires dans le code, ce qui, bien sûr, va à l'encontre du principe de l'API en premier et n'est pris en charge par aucun des utilitaires RAML,
À un moment donné, nous avons commencé à travailler avec RAML en tant que langage plus flexible et, par conséquent, nous avons dû faire beaucoup de nos propres mains. Par exemple, l'un des projets utilise l'utilitaire
ramlfications dans les tests unitaires, qui ne prend en charge que RAML 0.8. J'ai donc dû ajouter des béquilles pour que l'utilitaire puisse «manger» RAML version 1.0.
Dois-je choisir?
Après avoir participé à l'ajout d'un écosystème de solutions pour RAML, nous sommes arrivés à la conclusion que nous devons convertir RAML en Swagger 2 et déjà y réaliser toutes les automatisations, vérifications, tests et optimisations ultérieures. C'est un bon moyen de tirer parti à la fois de la flexibilité de RAML et de la prise en charge des outils communautaires de Swagger.
Pour résoudre ce problème, il existe deux outils OpenSource qui devraient assurer la conversion des contrats:
- oas-raml-converter est maintenant un utilitaire non pris en charge. En travaillant avec elle, nous avons constaté qu'elle a un certain nombre de problèmes avec des RAML complexes qui sont «réparties» sur un grand nombre de fichiers. Ce programme est écrit en JavaScript et effectue une traversée récursive de l'arbre de syntaxe. En raison de la frappe dynamique, il devient difficile de comprendre ce code, nous avons donc décidé de ne pas perdre de temps à écrire des correctifs pour un utilitaire mourant.
- webapi-parser est un outil de la même entreprise, qui prétend être prêt à tout convertir, dans toutes les directions. À ce jour, la prise en charge de RAML 0.8, RAML 1.0 et Swagger 2.0 a été annoncée. Cependant, au moment de notre étude, l'utilitaire était EXTRÊMEMENT brut et inutilisable. Les développeurs créent une sorte d' IR , ce qui leur permettra d'ajouter rapidement de nouvelles normes à l'avenir. Mais pour l'instant, tout cela ne fonctionne tout simplement pas.
Et ce ne sont pas toutes les difficultés que nous avons rencontrées. L'une des étapes de notre pipeline consiste à vérifier que la RAML du référentiel est correcte par rapport à la spécification. Nous avons essayé plusieurs utilitaires. Étonnamment, ils ont tous maudit nos annotations à différents endroits et avec de mauvais mots complètement différents. Et pas toujours le cas :).
En fin de compte, nous nous sommes installés sur le projet désormais obsolète, qui a également un certain nombre de problèmes (parfois il tombe à l'improviste, a des problèmes lors du travail avec des expressions régulières). Ainsi, nous n'avons pas trouvé de moyen de résoudre les tâches de validation et de conversion basées sur des outils gratuits, et avons décidé d'utiliser un utilitaire commercial. À l'avenir, lorsque les outils OpenSource seront plus développés, la résolution de ce problème pourrait devenir plus facile. Entre-temps, le temps et le travail nécessaires à la «finition» nous ont semblé plus importants que le coût d'un service commercial.
Conclusion
Après tout cela, nous avons voulu partager notre expérience et noter qu'avant de choisir un outil pour décrire les contrats, vous devez déterminer clairement ce que vous en voulez et quel budget vous êtes prêt à investir. Si vous oubliez OpenSource, il existe maintenant un grand nombre de services et de produits qui vous aideront à vérifier, convertir, valider. Mais ils sont chers et parfois très chers. Pour une grande entreprise, ces coûts sont tolérables, mais pour une startup, cela peut devenir un gros fardeau.
Définissez un ensemble d'outils que vous utiliserez ultérieurement. Par exemple, si vous avez juste besoin d'afficher le contrat, il sera plus facile d'utiliser Swagger 2, qui possède une belle API, car en RAML, vous devez lever et maintenir le service vous-même.
Plus vous aurez de tâches, plus vous aurez besoin d'outils, et ils seront différents pour différentes plates-formes, et il est préférable de vous familiariser immédiatement avec les versions disponibles pour faire un choix qui minimise vos coûts à l'avenir.
Mais il vaut la peine de reconnaître que tous les écosystèmes qui existent aujourd'hui sont imparfaits. Par conséquent, si l'entreprise a des fans qui aiment travailler en RAML, car «cela vous permet d'exprimer vos pensées de manière plus flexible», ou, au contraire, préférez Swagger, car «c'est plus compréhensible», il est préférable de les laisser travailler dans ce qu'ils Nous y sommes habitués et nous le voulons, car les outils de tous les formats doivent être finalisés avec un fichier.
Quant à notre expérience, dans les articles suivants, nous parlerons du type de contrôles statiques et dynamiques que nous effectuons sur la base de notre architecture RAML-Swagger, ainsi que de la documentation que nous générons à partir des contrats et de la façon dont tout cela fonctionne.