API & Industrialisation : intégration et déploiement continu

Clément Séguy
neoxia
Published in
9 min readMar 31, 2020

Cet article a été coécrit avec Alexandre Brun

Une stratégie API au sein de l’entreprise passe par la mise en place de bonnes pratiques d’organisation au sens général. Dans cet article, nous vous proposons d’aborder les concepts d’intégration et de déploiement continus relatifs aux cycles de vie des APIs.

En effet, si une API doit être conçue, développée et testée, elle doit également être améliorée pour tenir compte des retours de vos utilisateurs, clients, partenaires et consommateurs de données (après tout, leurs besoins vont continuer d’évoluer). Ainsi, l’amélioration continue de vos APIs doit être industrialisée. Pour parvenir à une maîtrise acceptable des changements que vont vivre vos APIs, toute modification doit être planifiée et surtout automatisée. En d’autres termes : AUCUNE action manuelle en production ne doit avoir lieu.

Cet objectif — qui est le nôtre lorsque nous mettons en place une architecture API — est atteignable au travers de bonnes pratiques que nous vous recommandons de mettre en place.

Intégration continue (CI)

Un logiciel évolue : de nouvelles fonctionnalités peuvent être ajoutées a posteriori et des bugs peuvent être corrigés.

La démarche d’intégration continue est motivée par le besoin d’intégrer sereinement les évolutions d’un projet informatique, en vérifiant rapidement la validité d’une modification de code avant de la diffuser.

Pour rappel, une API est un contrat qui définit les formats d’échange entre le producteur et le consommateur d’un service. Les modifications — majeures ou mineures — d’une API doivent être limitées et parfaitement maîtrisées. Il est donc extrêmement important d’avoir une maîtrise complète de ce processus pour les repérer en amont.

Toutefois, dans le domaine des APIs, nous devons aller plus loin que les simples tests de non régression. Nous sommes confrontés à des dépendances entre éléments beaucoup plus intriqués et nous devons opérer sur deux niveaux :

  • Le niveau backend, pour lequel nous mettons en place les différents principes de l’intégration continue que sont la centralisation du code, sa mise à jour régulière, l’automatisation de sa compilation et des tests unitaires, le contrôle automatique de la qualité du code et enfin l’automatisation du déploiement de la version du code.
  • Le niveau middleware. Ici, les principes de CI évoqués ci-dessus ne s’appliquent pas forcément. C’est la raison pour laquelle nous vous recommandons vivement de bien connaître votre architecture et ses éléments clés, ou de vous faire accompagner par un professionnel.

Nous allons pour cet article nous arrêter sur quatre points importants dans la chaîne d’intégration continue.

Il existe déjà beaucoup de documentation et articles traitant des tests unitaires, et ce n’est pas le sujet de cet article — seulement un de ses composants. Nous allons donc partir du principe que c’est une notion acquise par le lecteur. Rappelons toutefois qu’il vous faut viser la couverture maximale de tests pour votre code. Le principe de Pareto s’applique très bien à ce domaine : visez environ 80 % de couverture de code, pour que le développement des tests reste une tâche efficace. Les experts Neoxia étant avant tout des amoureux du beau code, la couverture de test doit s’appliquer PARTOUT (c’est-à-dire dans toutes les briques) !

Les tests d’intégration sont indispensables car l’architecture étant par nature distribuée sur plusieurs composants, il vous faut les tester séparément et ensemble. Ainsi, le proxy doit être testé et ne peut l’être qu’à travers des tests d’intégration. Chez Neoxia, nous utilisons Apickli pour sa simplicité de mise en place et sa syntaxe Gherkin (que le Product Owner peut prendre en main rapidement). L’intérêt de tester le proxy nous ramène à un de nos mantras API : s’assurer que l’on ne casse pas le contrat avec nos consommateurs.

Attention toutefois, l’objectif n’est pas de tester fonctionnellement les APIs, mais plutôt le contrat. On souhaitera vérifier qu’un comportement donné (HTTP status code, headers, format et structure de la réponse) est observé après une requête précise. On ne s’attardera pas sur le comportement métier (“j’attends telle réponse précise après telle requête précise”).

Ces tests d’intégration nous permettent de déterminer et de valider une version logicielle pour chaque composant. Veillez à être attentif aux versions logicielles des autres briques. La responsabilité de l’intégration continue est de suivre les versions logicielles de toutes les briques, backend ou proxy, et surtout leur compatibilité.

Pour aller plus loin dans la détermination d’une version logicielle, nous vous recommandons de pratiquer vos développements sur plusieurs branches et d’établir une stratégie de branche adaptée (par exemple GitFlow). Il existe beaucoup de littérature sur ce thème, mais pour illustrer notre avis sur la question, nous utilisons une stratégie GitFlow standard à Neoxia : une branche par environnement, des branches feature/* pour les fonctionnalités et des branches hotfixes/* pour les corrections. Ainsi, nous conservons une lecture claire et standardisée de l’ensemble de notre code.

C’est également la responsabilité du processus de CI que de suivre les versions de l’API. De manière classique, ce processus est responsable de la publication des nouveaux artefacts (exemples : .jar pour les backends, proxies pour la gateway, fichiers de migration…). Ici, il va également être responsable d’un nouvel artefact : la version de l’API exposée à vos clients (c’est-à-dire la version du fichier OpenAPI publié). Pour plus d’information sur la gestion de version d’une API, vous pouvez vous rendre ici.

Déploiement continu (CD)

La mise en place d’un processus de déploiement continu est un pré-requis nécessaire à l’atteinte de notre objectif “aucune action manuelle en production”. Cet article n’a pas pour vocation de définir ou d’argumenter en faveur du CD, il existe une littérature riche à ce sujet. De nombreux outils différents offrent des fonctionnalités similaires : GitLab CI, Azure DevOps, Jenkins, Bitbucket… Tous permettent de déployer automatiquement des services, en coordination avec Docker, Ansible ou autre. Cet article se positionne de manière agnostique sur ce point.

En premier lieu, les backends doivent être déployés automatiquement. Ce déploiement doit s’appuyer sur la CI précédemment exécutée. Un soin particulier doit être apporté à la gestion du cycle de dépendance entre ces applications, notamment dans un contexte où l’on utilise des microservices pour développer des APIs. De nombreux articles et ressources existent à ce sujet (configuration par environnement, protection des secrets, bonnes pratiques… en fonction des produits et langages utilisés).

Tout comme les backends, la gateway (ou proxy) est, elle aussi, déployée automatiquement. Ce middleware est un élément clé de l’architecture API, il est donc primordial d’être parfaitement serein quant à sa robustesse pendant la phase de déploiement. Même s’il n’est pas toujours possible de la tester unitairement, elle doit être testée au travers de tests d’intégration. Ce point n’est pas négociable puisque c’est la porte d’entrée principale de votre SI. Ces tests doivent alerter immédiatement les équipes de développement et DevOps si une modification de la gateway a un impact sur le contrat de service de l’API. Un point d’attention : il peut être nécessaire de déployer la nouvelle version de la gateway pour pouvoir la tester. C’est la raison pour laquelle les tests d’intégration doivent être automatisés (ainsi, pas d’oubli ni de mauvaise manipulation !).

Ainsi, définir une stratégie de rollback est nécessaire pour garantir que le système est cohérent à tout moment. C’est une stratégie classique pour les équipes DevOps mais dans ce contexte, elle devient critique puisqu’il est nécessaire de déployer la gateway pour la tester. Si un échec intervient au milieu de la chaîne de déploiement (par exemple, les tests de la gateway échouent ou bien un élément déployé a un impact inattendu sur un autre), il faut appliquer le rollback sur l’ensemble du système : backends, gateway, migrations… Grâce à elle, en partant du principe que nous disposons d’un minimum de 4 environnements (dev, staging, préproduction et production) et à la condition que tout soit automatisé dès l’environnement de développement, les surprises en production sont extrêmement limitées.

Enfin, au bout de la chaîne de déploiement, nous trouverons la mise à jour du Developer Portal. Idéalement, votre API est documentée et communiquée à vos clients au travers d’un Developer Portal. La mise à jour de ce document doit, elle aussi, être automatisée.

Publication des changements

L’intégration et le déploiement continus ont pour finalité de valider un changement de code. Cette modification doit être communiquée auprès des souscripteurs de votre contrat d’API. Ainsi, par ces changements, vous validez une nouvelle version de votre API (cf. notre article sur les bonnes pratiques). Qui est responsable de la validation de ce nouveau contrat, de sa diffusion, et par quels moyens ? Dans cette troisième et dernière partie, nous allons aborder la partie relative à la publication des changements.

Nos différents retours d’expérience nous permettent de recommander plusieurs bonnes pratiques à mettre en place au sein de votre organisation.

Tout d’abord, il faut déterminer le périmètre de chaque produit API. Il est possible qu’un “API Product Owner” (API-PO) ait la charge d’un ou plusieurs domaines fonctionnels. Par exemple, un API-PO peut être responsable du domaine “Contrats” ou “Ressources”, ou des deux en même temps.

Ensuite, il vous faut identifier le responsable du ou des contrats API. Cette responsabilité va à l’API-PO. Ce dernier doit avoir un profil mixte technique-métier, et être sensibilisé aux pratiques de Domain-Driven Design : l’idéal est qu’il soit capable de mettre les mains dans le moteur et de bien connaître les caractéristiques de l’activité. Son rôle va être de concevoir, cadrer et piloter les APIs dont il a la charge.

Enfin, il reste à donner le rythme. C’est toujours cet API-PO qui va définir quand et comment seront publiées les modifications de ses APIs dans son domaine de responsabilité. Il est seul responsable de la mise à jour des documents de spécifications de ses APIs (documents OpenAPI) et gère les versions via Git, pour une cohérence avec les modifications de code. Il pilote ensuite les développements tel un “PO classique”. Enfin, il teste et valide les livraisons.

Dans un précédent article, nous expliquions qu’un des facteurs clés du succès de l’API-sation de votre système d’information est l’adoption rapide de vos APIs par les consommateurs (développeurs, métiers, etc.). Cette adoption passe notamment par un outil indispensable qu’est un portail développeur.

Conclusion

Le challenge principal de l’industrialisation du système est la synchronisation des déploiements entre chaque brique composant vos APIs : backends, microservices interdépendants, middleware et, éventuellement, les applications frontales.

Il arrivera régulièrement de déployer une nouvelle version d’un backend ayant un impact direct sur un autre composant (autre backend ou gateway) ; c’est le rôle du process de déploiement continu et de la stratégie de rollback. Comment garantir qu’une livraison ne déclenche pas d’effet inattendu sur les autres éléments du système API ? S’assurer que l’organisation et les process en place répondent aux points suivants est un minimum :

  1. Les dépendances entre les briques sont identifiées, explicites et documentées ;
  2. Les actions de CI et de CD sont automatisées ;
  3. Des tests unitaires et d’intégration sont exécutés à chaque livraison ;
  4. Les artefacts générés (backends, middleware, librairies génériques…) sont correctement manipulés et stockés ;
  5. On dispose d’une stratégie de rollback en cas d’échec d’un déploiement — idéalement, cette réponse est automatisée ;
  6. Un monitoring est en place sur toute la chaîne que constituent nos APIs ;
  7. Avoir mis en place (et améliorer de manière continue) un système d’alerte en cas de défaillance de l’une des briques du système.

Afin de maîtriser les changements dans le cycle de vie de vos APIs, les modifications doivent être planifiées et surtout automatisées. Nous avons donc fait nôtre ce mantra — AUCUNE action manuelle en production ne doit avoir lieu — que nous vous recommandons d’adopter !

Cet article a été coécrit avec Alexandre Brun

Dossier API Management par Neoxia

Retrouvez ici tous nos articles concernant les APIs.

--

--

Clément Séguy
neoxia
Writer for

Passionné par les nouvelles technos, l’espace, l’histoire et les jeux de société. Lead Dev @Neoxia