Versioning des services: principes et éléments d’architecture…

Dans une implémentation SOA, un service n’a de sens que s’il est invoqué par plusieurs applications ou blocs applicatifs. Par conséquent, tout changement survenant sur un service impacte l’ensemble des consommateurs de ce service. Non seulement ces changements peuvent coûter chers, en plus, l’autonomie du service est un fondement de la mise en œuvre d’une architecture orientée services. L’autonomie se traduit par le fait que le service peut être modifié, déployé et maintenu indépendamment des consommateurs qui l’invoquent.

La façon la plus répondu pour faire face aux changements des services, c’est le versioning. Cela se traduit par la coexistence de plusieurs versions du même service, chacune est utilisée par un ou plusieurs consommateurs. L’introduction de la coexistence de multiples versions d’un même service permet d’avoir des cycles de vie indépendants entre fournisseurs et consommateurs de services, ce qui minimise les impacts globaux sur l’implémentation SOA.

versioning_gene_v1

Néanmoins, gérer les versions de services est loin d’être anodin. Sans une approche bien définie, cela pourrait mettre en péril le succès de l’adoption d’une architecture orientée services.

Même si l’approche de versioning peut paraître simple, il est indispensable de traiter les volets suivants entre fournisseurs et consommateurs de services:
La granularité du versioning: vu du client, la notion de versioning doit porter sur le service comme entité à part entière. On parle alors de versioning fonctionnel. Le versioning technique (c’est-à-dire le versioning unitaire du format du message de la requête, du format du message de la réponse, du type de transport, etc.) est à gérer en interne par le fournisseur de service d’une façon transparente par rapport aux consommateurs.

L’unité de versioning: il est indispensable de distinguer les versions majeures (V1, V2, etc.) des versions mineures (V1.x, V2.y) dans l’implémentation d’un service. Une version mineure porte sur une optimisation de performances, correction de bugs, évolution mineure du contrat de service sous condition de compatibilité ascendante entre versions, etc. alors qu’une version majeure porte sur des modifications/évolutions fonctionnelles ou techniques impactant fortement le contrat de service (avec rupture de la compatibilité ascendante) entre fournisseur et consommateurs du service.

La traçabilité d’une version: il est important de détailler, tracer et partager les changements survenus sur les différentes versions d’un service. Cela permettra aux consommateurs d’étudier les impacts fonctionnels et techniques sur leurs applicatifs et planifier des trajectoires de migration/évolution.

Le cycle de vie d’une version : Le cycle de vie doit être partagé par l’ensemble des acteurs pour que chacun puisse gérer l’évolution des versions de services que l’application qu’il gère invoque. Par exemple, la disparition d’une version de service peut profondément impacter le bon fonctionnement d’une application. En revanche, le fournisseur de service ne peut gérer indéfiniment toutes les versions. Un compromis sur le cycle de vie d’une version de service doit être trouvé entre consommateurs et fournisseur.

La stratégie de déploiement et d’invocation des différentes versions d’un service : Trois principales stratégies de versioning se distinguent:

    Stratégie 1 – Le versioning est porté par l’URI d’invocation du service

Cela implique qu’un catalogue de versions d’un même service soit géré par le fournisseur et partagé avec les consommateurs. Chaque version est considérée comme un service différent à part entière.

Illustration
versiong_str1

    Stratégie 2 – Le versioning est porté par la requête d’invocation du service

Cela implique qu’une unique «URI » soit exposé aux consommateurs. La version requise par le consommateur doit être mentionnée dans la requête.

Tip: La version doit être positionnée dans un quelconque entête technique de telle façon que le fournisseur de service n’aura pas à interpréter le contenu fonctionnel de la requête.

La mise en place d’un composant façade est indispensable pour cette stratégie de versioning. Il assure les 2 principales fonctions suivantes :
► Le routage de la requête vers la version requise par le consommateur
► L’adaptation des formats entrants/sortants par rapport aux formats requis par les différentes versions du service.

Pour assurer la stabilité d’un contrat d’interface, il est important à noter que le service façade doit s’adapter à tous les contrats d’interface définis. Ce qui implique la mise en œuvre d’un macro-service le plus générique possible proposant un contrat d’interface n’exposant aucune notion de versioning aux consommateurs. Ce qui rajoute une complexité supplémentaire aux fournisseurs de services qui sont menés à gérer ce type de service.

Illustration

versioning_str2

    Stratégie 3 – Le versioning est géré par un composant façade du fournisseur

Cette stratégie est semblable à la stratégie 2 en termes de stabilité de contrat d’interface. Seule différence, le client ne fournit aucune version dans sa requête d’invocation mais plutôt un identifiant qui sera exploité par le composant façade pour invoquer la bonne version du service.

Illustration
versioning_str35

Le tableau suivant compare ces 3 stratégies en distinguant la vue « consommateur » de celle du « fournisseur » du service.
tab_compa_v23

    Quelle stratégie adopter?

Pour minimiser l’impact sur le consommateur et donner plus de flexibilité au fournisseur dans sa gestion des versions, la combinaison des stratégies 1 et 3 est le choix le plus judicieux:
► Les versions majeures seront gérées selon la stratégie 1
► Les versions mineures seront gérées selon la stratégie 3

Cela permet notamment d’éviter:
► les macro-services complexes et ingérables
► d’impacter les consommateurs à chaque mise en œuvre d’une version mineure.

La traduction architecturale générale est illustrée par le schéma ci-dessous :
preco1

4 commentaires sur “Versioning des services: principes et éléments d’architecture…”

  • Cet article est intéressant, mais il me semble qu'il manque une partie essentielle dans le versioning de services: comment gérer les problèmes comme la modification du schéma de BD sous-jacente nécessitée par une nouvelle version majeure d'un service. En effet, gérer plusieurs versions de services me semble finalement très simple par rapport à la façon de gérer des modifications de schéma. Que faire : * ne jamais modifier le schéma ? * Créer une nouvelle table modifiée à côté de l'ancienne, auquel cas comment gérer la synchro entre ces deux tables ? Merci d'avance pour des réflexions ou des pistes sur ce sujet.
  • Il y avait déja eu un article sur le meme genre de sujet: https://blog.octo.com/versioning-de-services-rest/ Je suis bien d'accord avec la remarque de Baptiste, on oublie souvent de prendre en compte les problématiques impactantes du genre modif de MPD. Dans ce cas, est-ce que la version majeure précédente a encore du sens ? (Sachant que lorsqu'on a une modif de MPD, on fait la modif sur la base de prod, et on n'a QU'UNE SEULE BASE de données) Si on ajoute au MPD une colonne obligatoire alors le service précédent n'a plus de sens. J'ajouterai juste à l'article que si les versions mineures sont juste remplacées de manière transparente, alors les solutions 2 et 3 sont identiques je crois. Cdt Gilles S
  • Ca me rappelle aussi un très bon article d'InfoQ sur le sujet : http://www.infoq.com/articles/contract-versioning-comp2 qui détaille cette problématique complexe à gérer.
  • Bjr Baptiste, Effectivement, la question posée est intéressante. Néanmoins, l'évolution d'un contrat d'interface entre un consommateur et un fournisseur de service n'implique pas systématiquement la mise à jour d'un MPD. Les champs additionnels rajoutés à un contrat de service peuvent provenir de plusieurs sources: un autre service appelé en amont, une autre table de la même base ou d'une base différente, etc. Maintenant revenant à la question, plusieurs pistes existent permettant de maintenir/faire évoluer des tables en relation avec un service exposé: - Définition d'un méta-modèle pour une évolution facile du modèle de données - Définition d'une table propre au service synchronisé en temps réel avec la/les table(s) applicative(s) - Modification tout simplement du modèle de données en prévoyant une action d’export/import des données. Tout cela pour dire qu’il n’y a pas LA solution. Ça dépend du contexte et des contraintes imposées. Cdlt.
    1. Laisser un commentaire

      Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *


      Ce formulaire est protégé par Google Recaptcha