Le versioning des Web Service

image_pdfimage_print

Récemment, j’ai été confronté à la remise à plat d’un SI avec la volonté d’articuler celui-ci autour de la SOA. L’utilisation de Web Service n’a de valeur que si ces derniers sont utilisés par de multiples applications. Mais dans ce cas, comment gérer l’indépendance des services qui est une des briques angulaires de cette architecture. En effet, chaque service doit pouvoir vivre de son coté (modification, maintenance, déploiement) sans impacter (ou tout du moins le moins possible) ses consommateurs. Donc une stratégie de versioning doit être mise en place ! Mais comment ?

Versioning fonctionnel

Dans le cas d’un web service, je parlerai de versioning fonctionnel car c’est cette dernière qui va intéresser le consommateur. En gros, il suffit de voir le versioning fonctionnel comme un changement de contrat ou d’interface, on se moque de l’implémentation, mais si les entrées ou la sortie change alors la version fonctionnelle change.

De façon classique, un Web service évolue de la façon suivante :

  • Evolution majeure : Va signer des modifications, évolutions fonctionnelles ou techniques impactant directement le fameux contrat liant le fournisseur et le consommateur.
  • Evolution mineure : Va signer toutes modifications ne modifiant pas le contrat d’utilisation (optimisation, correction de bugs), enfin bon tout ce qui ne change pas les entrées obligatoires et les informations de sortie de façon à impacter la compatibilité ascendante.

La communication

Peu importe la teneur des évolutions, il est important de communiquer sur 2 points :

  • Traçabilité : Tracer les changements impactants les différentes versions d’un service. De cette façon le consommateur pourra étudier les impacts fonctionnels et techniques qui en découlent et planifier la prise en compte de celles-ci.
  • Cycle de vie : Tous les acteurs devront être mis en courant du cycle de vie de tout ou une partie du service. Le fournisseur ne peut décemment pas gérer ad vita eternam toutes les versions. Mais la suppression d’une version d’un service peut être fortement impactant pour le client. Par conséquent, un arrangement doit être trouvé entre client et fournisseur.

Quelle stratégie ?

J’ai 2 stratégies à vous proposer :

  1. Version portée par l’URI d’appel
  2. Version portée par la requête d’appel

Version portée par l’URI d’appel

En gros, le fournisseur de service va proposer un ensemble d’URI permettant d’accéder aux différentes versions des services. Chaque version est finalement un Web Service à part entière.

schema_version-uri

Dans le schéma ci-dessus, on peut voir que l’URI d’appel possède un descripteur de version. Pourquoi une version différente ? Parce que les contrats d’entrée et de retour ont changés. Et le contrat de retour aura changé lui aussi car le 2ième paramètre de la V2 permet de spécifier le détail des informations renvoyées et donc le XML/JSON renvoyé a été modifié dans ce but.

Version portée par la requête d’appel

On expose une seule URI commune aux clients et le contrat d’entré demande dans la requête une en-tête qui permettra au macro-service (façade) de composer et de faire l’appel vers le bon service.

schema_version_header

Il est a noter qu’un travail doit être fait en amont pour que le contrat d’entrée et de sortie soit assez générique pour répondre et transporter à tous les appels sous-jacents.

Version portée par le fournisseur

Le cas précédent peut être rendu encore plus pratique et moi dépendant de la version de service. Un code sera utilisé lors de l’appel de ce code sera interprété par la façade afin de savoir quelle version sera appelée afin de remplir le contrat d’appel. Cela permet de ne pas avoir de lien direct avec la version de Web Service.

Cette identifiant peut être passé de n’importe quelle façon :

  • header : Ma solution préférée, pratique car fonctionne pour toutes les méthodes (GET/POST/PUT/DELETE etc.).
  • URL params : Moyen dans le cadre de services REST.
  • URL parts : Simple dans le cadre de services REST mais peu adapté aux autres types de service.
  • form-data : Personnellement, je ne suis pas fan car vient se mélanger aux données métiers du service.

Pour synthétiser

En définitif, il semble que les deux solutions soient assez complémentaires.

  • Pour gérer les versions majeures, la solution 1 me parait être la plus pérenne à mettre en place.
  • Pour gérer les version mineures, la solution 3 me parait être la meilleure dans le sens ou ce genre de montée de version n’impacte jamais (normalement) les contrats  du services.

La combinaison de ces deux solutions va permettre :

  • Eviter l’utilisation de mega-service complexe à maintenir
  • Ne pas obliger les consommateurs à suivre de façon forcée la moindre évolution.

Un problème nommé base de données

Du fait de la cohabitation des Web Service de versions différentes émerge régulièrement une problématique de données : “Mais comment va t’on gérer les modifications de schéma ?”,  “Faut-il qu’on versionne aussi la base de données ?” , etc. Eh bien c’est simple ! Je pense qu’il s’agit la d’un vrai/faux problème ! En effet, au début de cette article on a bien dit que le Web Service devraient être parfaitement autonome, par conséquent la gestion de la base de données sous-jacente n’est pas un problème lié au versioning de Web Service mais plus une problématique lié à l’évolution technique du Web Service.

Dans ce cas, il est bon de considérer que les développeurs ne sont pas que de simple machine à coder mais aussi des professionnels réfléchis capable de gérer l’évolution de la base de données … comme des grands ! Les solutions sont multiples (script, DBA, ORM tools, Domain Driven Design, etc.). Mais nous sommes bien d’accord, il faut que l’architecture de base soit bien pensée et que les montées de schéma (absence de champs, changement de type, etc.) soit gérées par le code. Une application bien réfléchie dés le départ sur une base de Domain Driven Design devrait encaisser ce genre d’organisation sans trop de souci.

Pour conclure

Il n’y a pas qu’une façon de gérer le versioning de Web Service. Certains ne le gèrent pas et font subir toutes leurs modifications au consommateur en mode “one to one” ; Si je change, tu change aussi ! Si la communication est au rendez-vous, tout se passera bien puisque dans ce cas le temps aura été pris afin que les impactes soit gérés chez le consommateur. Mais, malheureusement, ce n’est pas toujours le cas, souvent la communication vacille et c’est un développeur qui se rend compte à posteriori que tel ou tel Web Service a changé de contrat ou mieux qu’il n’existe plus et ce … sur le tare, au mieux en dev ou en recette au pire en prod !!!

Dés le début du travail sur vos Web Service, prévoyez votre cycle de vie et communiquez le massivement. Une bonne page wiki par Web Service permettra d’avoir une visualisation rapide et simple sur les fonctionnalités passées (disparues), présentes, et futures (à venir) et sera la réponse à toutes questions du genre :

  • Le Web Service A, il s’interroge comment ?
  • Le Web Service B, il ne fonctionne plus ?
  • Le Web Service C, il répond quoi déjà ?
  • Le Web Service D, il ne donne plus la valeur de tel attribut ?
  • etc.

Leave a Reply

Your email address will not be published. Required fields are marked *