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

le 26/05/2009 par Karim Ben Othman
Tags: Évènements

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