Architectures orientées Services (SOA)
"pluralitas non est ponenda sine necessitate"

par Jean-Paul Figer, ARMOSC

Publié le - Mis à jour le

vide

Principales rubriques

Cet article est publié sous la référence H6 002 dans le Traité sur l'Informatique des Techniques de l'Ingénieur.

Cet article est destiné principalement à ceux qui s'intéressent à l'architecture des systèmes informatiques. Il explique la "révolution" qui se cache derrière le style SOA, la manière de reconnaître une architecture SOA et les conséquences de son introduction dans les entreprises.

Le sigle SOA (Service Oriented Architecture ou Architecture orientée services) est devenu à la mode début 2005 grâce aux succès du déploiement de l'Internet dans le public et dans les entreprises. En quelques mois, tous les fournisseurs de produits ou de services se sont découverts plus SOA les uns que les autres. La lecture attentive de leur documentation laisse perplexe car des discours marketing ou techniques insipides démontrent à l'évidence que leurs produits ou méthodes, restés inchangés, ne sont conformes ni de près, ni de loin au style SOA.

Le style SOA peut s'appliquer à toutes les technologies pour tout type de réalisation. Cependant, la révolution SOA est tirée par les standards de l'Internet. C'est donc naturellement ce qui servira de cadre à cet article, en particulier pour les exemples.

Il existe deux groupes de travail du W3C (World Wide Web Consortium) qui couvrent le sujet SOA, un sur l'architecture du World Wide Web dont la lecture est indispensable et un autre sur les web services dont nous verrons plus loin les graves faiblesses.

La traduction de certains termes anglais en français n'étant pas encore estampillée par l'académie française, j'ai mis [entre crochets] le terme anglais dont ma traduction est issue.

Quelques définitions pour dresser le décor

La réutilisation en logiciel se définit par des modèles, des architectures et des styles.

Un modèle [pattern] est défini par Martin Fowler ("Analysis Patterns", 1997) comme "une idée qui a été utile dans un contexte particulier et qui le sera probablement dans d'autres contextes". Cette notion de modèle est valide à tous les niveaux, depuis le morceau de code qui résout un problème particulier jusqu'à un groupe de fonctions dans un domaine comme les télécommunications ou la comptabilité.

L'architecture logicielle d'un programme ou d'un système est la description de sa structure qui regroupe les composants logiciels, les connecteurs (propriétés externes de ces composants) et les relations entre les composants et les connecteurs.

Un style d'architecture définit une famille de systèmes en terme de modèles de structure, un vocabulaire de composants et de connecteurs et des règles ou contraintes sur leurs relations. Chaque style d'architecture a ses propres caractéristiques. L'évolution des styles d'architecture est généralement liée à l'évolution de la technologie.

Pour faire une comparaison avec l'architecture des bâtiments, le style d'architecture roman se caractérise par des murs porteurs donc épais sans possibilité de faire de grandes ouvertures alors que le style gothique fait reposer le poids de la structure sur des piliers. Les murs deviennent des éléments de décoration avec les vitraux. L'évolution des styles d'architecture est rendue possible par l'évolution de la technologie. L'invention de la brouette, de la roue de carrier pour monter les pierres et la fabrication de maquettes ont permis le déploiement du style gothique.

Les styles d'architecture sont donc des "modèles de conception" [design patterns] pour la structure et les interconnexions entre les systèmes logiciels.

On peut distinguer trois grands styles d'architecture pour les systèmes distribués

  • Architectures orientées objets
  • Architectures orientées ressources
  • Architectures orientées services

Architectures orientées objets

Les architectures orientées objets nécessitent de communiquer avec l'instance particulière d'un objet qui se caractérise par son état, son comportement et son identité. Les communications sont par nature avec état [stateful] puisqu'il faut communiquer avec une instance d'objet crée au préalable. L'information d'état est donc gérée sur le serveur. Toute communication avec l'objet impose un aller-retour avec le serveur. Les protocoles utilisés habituellement (IIOP, DCOM ou RMI) ne sont pas conformes aux standards de l'Internet. C'est la faillite totale de l'extensibilité [scalability] de ce style d'architecture dans un environnement largement distribué qui explique le passage aux styles d'architectures orientées ressources ou services. Pour plus de détails, voir en annexe une comparaison ressource/objet.

Architectures orientées ressources

En informatique, une ressource est tout ce qui a une identité. Une page, un sous-ensemble d'une page ou une liste de documents sont des ressources. Les architectures orientées ressources nécessitent d'extraire des instances d'une ressource particulière comme par exemple l'extraction d'un page HTML par une requête HTTP GET ou l'extraction d'une ligne d'une table d'une base de données par une commande SQL SELECT. Les instances des ressources sont identifiées par des données de type adresse dans la requête comme l'URI du HTTP ou la clause WHERE de la commande SQL SELECT. Les ressources ont un état et une identité. L'extraction d'une ressource crée un instantané de l'état de la ressource du coté client. Cet instantané peut être conservé dans un "cache" pour une utilisation ultérieure sans avoir à extraire à nouveau les données. La copie maître de la ressource reste sur le serveur. La mise à jour des ressources se fait soit par remplacement total (HTTP PUT), soit par remplacement partiel (HTTP POST ou SQL UPDATE). Les modifications de la copie maître sur le serveur ne sont pas automatiquement répercutées sur la copie client.

Architectures orientées services

Un service est une fonction logicielle autonome [self contained] et sans état [stateless] qui accepte des requêtes et qui renvoie des réponses au travers d'un interface standard bien défini. Un service est donc une unité de traitement qui fournit un résultat à un consommateur. Fournisseurs et consommateurs sont habituellement des agents logiciels qui agissent par délégation de leurs propriétaires. Les services ne doivent pas dépendre de l'état d'autres fonctions ou d'autres traitements externes. Les technologies employées pour réaliser un service comme le langage de programmation ne font pas partie de la définition d'un service.

Dans une architecture orientée services, tous les messages ou toutes les requêtes pour un service spécifique sont envoyés à l'adresse unique du service.

Définition du style d'Architecture Orientée Service (SOA)

Le style d'architecture orientée services (SOA) est un style d'architecture qui se définit par :

  • Un couplage lâche [loosely coupled] entre les composants d'un système pour ne pas dépendre de l'état d'autres services et pour faciliter la réutilisation,
  • Des services sans état [stateless] pour faciliter l'extensibilité [scalabilty] et l'éventuelle orchestration,
  • Des services fortement interopérables ce qui implique l'utilisation de vocabulaires de données très bien définis. 

Comme on peut le constater, il n'y a rien de nouveau sous le soleil. Les concepts de couplage lâche, sans état ou d'interopérabilité des données existent depuis pratiquement les débuts de l'informatique. Ce qui a changé, c'est la portée de ces concepts autrefois limitée à des systèmes autonomes. Avec l'URI comme mode d'adressage de services, le couplage lâche est devenu minimal. Il n'y a plus besoin d'aucune information sur la localisation du service, le type de système, la méthode de programmation, le mode d'accès ou le nommage pour s'adresser à un service. Juste une chaîne de caractères sur un bout de papier suffit. De même, l'interopérabilité des données a fait d'énormes progrès. Dans le passé, il fallait choisir le jeu de caractères utilisé. On pouvait tout représenter (russe, chinois, grec, latin,...) mais pas mélanger. Le codage Unicode utf-8 est devenu universel dans le sens où tous les caractères sont possibles dans le même texte. C'est cette universalité qui change la donne. La valeur d'un service est proportionnelle à sa portée. C'est toute la différence entre Google et une recherche locale. En utilisant les bons modèles, une architecture orientée services peut avoir une portée universelle.

Comment choisir un style d'architecture ?

Le choix d'un style d'architecture est une décision très importante dans la conception de tout système informatique. Ce choix a des conséquences directes sur les performances, sur la réutilisation et sur l'interconnexion avec d'autres systèmes.

"pluralitas non est ponenda sine necessitate"

Le rasoir d'Ockham (ou d'Occam) est un principe de raisonnement que l'on attribue au moine franciscain et philosophe Guillaume d'Ockham, mais qui était connu et formulé avant lui. Énoncé au XVe siècle, ce principe dit : « Les choses essentielles ne doivent pas être multipliées sans nécessité » (version originale en latin : « pluralitas non est ponenda sine necessitate »). Aussi appelé « principe de simplicité », « principe de parcimonie », ou encore « principe d'économie », il exclut la multiplication des raisons et des démonstrations à l'intérieur d'une construction logique. Le principe du rasoir d'Ockham consiste à ne pas multiplier les hypothèses au-delà du nécessaire, et en d'autres termes à toujours privilégier aussi longtemps que cela reste compatible avec les observations l'hypothèse la plus simple parmi toutes celles qui sont échafaudées. Conan Doyle l'a souvent mis en pratique dans les déductions de Sherlock Holmes.
Extrait de Wikipedia

La démarche que je propose pour le choix d'un style d'architecture de systèmes informatiques consiste à privilégier la solution la plus simple et la plus économe en ressources, en temps de réalisation et en temps d'exécution. Le Web en général et tous les sites qui ont du succès avec plus de cent millions de visiteurs par mois comme Google, Yahoo, Ebay et Amazon utilisent tous les styles d'architecture orientées ressources et services. Lorsque ces ressources ou ces services résident sur l'Internet ou sur un Intranet, on emploie plus communément le terme de Web Services.

Un style d'architecture n'est pas un standard. En revanche, il s'appuie sur des standards. Lorsqu'on parle de Web services, les standards habituellement employés sont :

  • URI pour le nommage des ressources ou des services,
  • HTTP ou HTTPS pour le protocole de communication,
  • XML et XHTML pour les données et les documents,
  • Des liens hypermédia avec des types MIME pour la navigation et l'accès aux ressources,
  • Le DOM (Document object Model) comme plate-forme et interface indépendante d'un langage pour lire et modifier le contenu, la structure et le style des documents ,
  • Javascript comme langage de scripting pour manipuler le DOM,
  • PKI (Public Key Infrastructure et X509 pour la sécurité.

La sélection darwinienne de l'Internet a permis l'émergence de technologies simples, robustes et extensibles de un à un milliard d'utilisateurs. Dans le domaine des styles d'architecture, REST et SOAP sont les styles dominants.

  • REST est le style d'architecture orienté ressources et services qui a fait réussir l'Internet. C'est aussi le plus simple. Bien que le nom soit peu connu, c'est le style le plus répandu. Fidèle au principe d'Occam, c'est donc ce style que nous étudierons en détail.
  • SOAP est un style  d'architecture orienté services, plus complexe et moins répandu mais plus connu car poussé par les offreurs de produits traditionnels. Nous l'analyserons en le comparant à REST.

REST

Historique de REST

REST est l'acronyme de "Representational State Transfer" inventé par Roy T. Fielding dans sa dissertation "an architecture style of networked systems". Roy T. Fielding participe depuis 1994 aux travaux du W3C sur les sujets URI, HTTP, HTML et WebDAV et a été le co-fondateur du projet Apache, le serveur Web qui équipe 70% des sites Web de tout l'Internet (IIS de Microsoft n'a que 20%). REST décrit les caractéristiques du Web qui en ont fait son succès. L'explication de la signification de REST telle que donnée par Roy T. Fielding est la suivante : "Representational State Transfer évoque l'image du fonctionnement d'une application Web bien construite : un réseau de pages Web (une machine à états finis virtuelle) où l'utilisateur progresse dans l'application en cliquant sur des liens (transition entre états) ce qui provoque l'affichage de la page suivante (représentant le nouvel état de l'application) à l'utilisateur qui peut alors l'exploiter".

REST, un style d'architecture, pas un standard

REST est un style d'architecture, pas un standard. Il n'existe donc pas de spécifications de REST. Il faut comprendre le style REST et ensuite concevoir des applications ou des services Web selon ce style.

Bien que REST ne soit pas un standard, il utilise des standards. En particulier :

  • URI comme syntaxe universelle pour adresser les ressources,
  • HTTP ou HTTPS, protocole sans état [stateless] avec un nombre très limité d'opérations,
  • Des liens hypermédia dans des documents XML et XHTML pour représenter à la fois le contenu des informations et la transition entre états de l'application,
  • Les types MIME comme text/xml, text/html, image/jpeg, application/pdf, video/mpeg pour la représentation des ressources.

REST concerne l'architecture globale d'un système. Il ne définit pas la manière de réaliser dans les détails. En particulier, des services REST peuvent être réalisés en .NET, JAVA, CGI ou COBOL. Vous avez sans doute déjà réalisé des services REST sans le savoir comme Monsieur Jourdain faisait de le prose !

URI, Ressource et Représentation

Le Web est un espace d’information dans lequel les éléments intéressants -Ressources- sont désignés par des identificateurs globaux -URI-. URI est l'abréviation de "Uniform Resource Identifier". Les URI se composent de 2 sous-ensembles URL et URN dont la syntaxe détaillée est décrite ici.

ressource

En cliquant sur l'URI suivante http://fr.weather.com/weather/local/FRXX0076, vous obtenez la météo de Paris. Le fait de cliquer sur le lien indique au navigateur que vous voulez obtenir une représentation de la ressource désignée. Le navigateur reconnaît http comme protocole et envoie alors au serveur fr.weather.com une requête HTTP GET sur le port 80. En retour, le serveur lui envoie la représentation actuelle de la ressource /weather/local/FRXX0076. Cette représentation comporte deux parties, des métadonnées qui décrivent le contenu suivies par la représentation de la ressource :

Date: Mon, 15 Aug 2005 21:39:05 GMT
Server: Apache
Set-Cookie: LocID_fr_FR=FRXX0076; Domain=.fr.weather.com; Expires=Tue, 15-Aug-2006 21:39:05 GMT; Path=/
Keep-Alive: timeout=3
Connection: Keep-Alive
Content-Type: text/html;charset=ISO-8859-1
Cache-Control: private
Content-Encoding: gzip
Transfer-Encoding: chunked

200 OK

Dans ces métadonnées, on trouve

Content-Type: text/html;charset=ISO-8859-1

 ce qui indique que les données de la représentation de la ressource sont une page HTML codée dans le jeu de caractères ISO-8859-1.
Pour lire facilement ces métadonnées, je vous suggère d'utiliser Firefox et d'installer l'extension Web Developer.

Le Content-Type ou MIME Type est très important puisque c'est lui qui est utilisé par le navigateur pour déterminer le type du fichier, pas l'extension. C'est en fonction de ce type de fichier que le navigateur  déterminera l'action à accomplir (visualisation, téléchargement, etc..). Lorsque la même ressource existe sous plusieurs représentations ou plusieurs langages, il est aussi possible à l'agent utilisateur de "négocier" avec le serveur la représentation qui sera fournie. Les types MIME sont attribués par l'IANA.

Les URI ne sont pas limités au schéma HTTP. Voici quelques exemples classiques :
mailto:individu@adresse.org ,
ftp://ftp.futurenet.co.uk/pub/dailyradar/ ,
news:msnews.microsoft.com
sip:jfiger@figer.net

Il est fortement recommandé d'utiliser les schémas et les types MIME qui existent avant de songer à en créer d'autres. En réutilisant les schémas qui existent, on bénéficie automatiquement de tous l'outillage développé autour de ce schéma. C'est la méthode de réutilisation la plus efficace.

Cette notion d'URI est fondamentale car c'est le système global et unique d'identification du Web. L'URI est la pierre angulaire de l'architecture Web. Elle permet d'accéder en un "simple clic" à une multitude de protocoles et de représentations. La portée globale des URI entraîne un effet réseau global. Plus un identifiant est utilisé, plus sa valeur augmente.

Nommage

Le système d'URI a été largement déployé depuis les débuts du Web et les avantages des URI sont nombreux : liens, favoris, mécanismes de cache, indexation par les moteurs de recherches. En utilisant les URI, il est possible de déployer une application partout dans le monde sans infrastructure additionnelle comme des annuaires (registries). Déployer un autre système de nommage qui aurait les mêmes propriétés que les URI serait très long et très coûteux. IBM, SAP et Microsoft ont annoncé en décembre 2005 qu'ils abandonnaient l'effort entrepris depuis 5 ans autour d'UDDI pour associer un annuaire à SOAP !

Le premier principe de l'architecture REST consiste à identifier les ressources intéressantes avec des URI.

 

HTTP, GET et POST

Le deuxième composant de l'architecture REST est le protocole HTTP. Ce protocole comporte deux méthodes principales GET et POST et deux manières de transmettre des paramètres, soit dans l'URI, soit dans les données d'un formulaire.

Quand employer GET et quand employer POST ?

L'utilisation de GET est "sûre" [safe], c'est à dire que l'état de la ressource ne doit pas être modifié par un GET. Ceci autorise les liens, la mise en cache, les favoris. Il faut donc utiliser GET pour des opérations qui ressemblent à des questions ou à des lectures de l'état de la ressource. 

En revanche, il faut utiliser POST quand la demande ressemble à une commande, ou quand l'état de la ressource est modifié ou quand l'utilisateur est tenu pour responsable du résultat de l'interaction.

Deuxième principe de l'architecture REST : le HTTP GET est "sûr", c'est à dire que l'utilisateur ou son agent peut suivre des liens sans obligations.

La conséquence de l'idempotence du GET -deux accès successifs donnent le même résultat- rend l'utilisation du Web plus fiable car un deuxième clic sur un lien ne modifie pas le résultat. 

Le protocole HTTP comporte d'autres commandes moins souvent utilisées. HEAD qui est un GET qui ne renvoie que les métadonnées, pas les données. PUT et DELETE pour créer ou supprimer une ressource.

Il existe deux documents publiés par le W3C qui donnent tous les détails sur ces principes fondamentaux et dont la lecture est indispensable à tout architecte "Architecture of the World Wide Web" et "URIs, Addressability, and the use of HTTP GET and POST".

URI logique comme API universelle

L'identification des ressources est la pierre angulaire d'une architecture REST. La définition des URI ne peut donc être la conséquence d'un développement. Les URI doivent être spécifiées au moment de la conception. Les URL manipulées par les serveurs web sont des URL physiques qui reflètent la structure physique des répertoires d'un serveur. Elles comportent des extensions qui dépendent d'une technologie particulière comme .cgi, .aspx ou .php. Une très bonne solution consiste à représenter les URI de manière indépendante d'une technologie sous la forme d'un hiérarchie et à supprimer l'extension. Le plus simple pour comprendre est de consulter un exemple.

J'ai crée un groupe, exemple_rest, sous Yahoo Groupes. Son URI est la suivante


http://fr.groups.yahoo.com/group/exemple_rest

En cliquant sur le lien ci-dessus, le navigateur exécute une requête HTTP GET qui permet de d'obtenir une représentation de la ressource. Dans l'en-tête de la réponse, il est indiqué

Content-Type: text/html 

 On obtient donc l'affichage d'une page html.
Si on clique sur le bouton XML orange à droite dont l'URI est http://rss.groups.yahoo.com/group/exemple_rest/rss on obtient dans l'en-tête de réponse

Content-Type: text/xml

 et le navigateur affiche en XML le canal RSS de ce groupe.

En cliquant dans le menu de gauche sur "messages", on obtient la liste des messages avec l'URI http://fr.groups.yahoo.com/group/exemple_rest/messages
et le message n°1 avec l'URI
http://fr.groups.yahoo.com/group/exemple_rest/message/1 .
La logique de construction des URI est évidente. Construire l'application à partir de ces bases devient un jeu d'enfant.

Le site Del.icio.us de gestion et de partage de favoris est un autre exemple construit avec des URI logiques qui servent de base directe au système de navigation et de recherche du site.

Les URI indiquées sont des URI logiques indépendantes de toute technologie. Un  proxy ou un filtre placé sur le serveur fr.groups.yahoo.com transforme ces URI logiques en URL physiques qui font appel à des pages .aspx, .php ou autre avec des paramètres en fonction de la technologie utilisée. Cette manière de faire présente de nombreux avantages :

  • Indépendance par rapport à une technologie particulière,
  • Interface (API) universelle entre les composants et les agents utilisateurs,
  • Il devient très facile de vérifier les droits d'accès aux ressources au niveau du filtre. Voir le § sur la sécurité.
  • La sécurité du site web est renforcée puisqu'on ne peut plus faire d'attaques directes sur les URL des pages Web qui sont masquées.
  • Tout navigateur devient un client du pauvre et il est très facile de tester le comportement du système.
  • En utilisant https, on peut aisément chiffrer les communications rendant possible l'utilisation de l'application en toute sécurité sur l'Internet public et en Wi-Fi.

Voici un autre exemple pour démontrer l'intérêt des URI. Dans ce cas, le serveur renvoie un code barre construit dynamiquement à partir de l'URI sous la forme d'une image. http://www.barcodesinc.com/generator/image.php?code=JEAN-PAUL%20FIGER&style=165&type=C39&width=350&height=100&xres=1&font=3

Le Content-Type est image/jpeg. Le navigateur affiche donc une image. Je n'ose imaginer l'API compliquée, utilisable uniquement dans un contexte de programmation local, qu'inventerait un programmeur objet pour obtenir dynamiquement un code barre !

Et pour bien enfoncer le clou, imaginons un système Windows où chaque ressource aurait sa propre URI comme

/Démarrer/PanneauDeConfiguration/ConnexionsRéseau/Carte1394/TcpIp/automatique

Et la sécurité ?

La sécurité comme la performance est souvent l'excuse avancée pour faire compliqué alors que seule la simplicité des concepts permet d'atteindre cet objectif.

Comme c'est très bien expliqué dans le rapport PITAC de février 2005 remis au Président des Etats-Unis : Cyber Security, a crisis of Prioritization, la faiblesse du modèle habituel de défense périmétrique, généralement utilisé par les entreprises, est devenue douloureusement évidente. Ce modèle, fondé un peu sur le principe de la ligne Maginot, est censé protéger "l'intérieur" d'un système informatique d'un attaquant venu de "l'extérieur". Cependant, dès que la barrière est franchie à la suite d'une vulnérabilité logicielle ou d'une maladresse d'un opérateur, l'attaquant peut compromettre l'ensemble des systèmes sans guère plus d'efforts que pour en compromettre un. Ce n'est pas le seul problème de ce modèle. La distinction entre "intérieur" et "extérieur" s'effondre avec la prolifération d'équipements connectés et la complexité toujours croissante des réseaux interconnectés. Un modèle plus réaliste est le modèle de suspicion mutuelle. Chaque composant d'un système ou d'un réseau est naturellement méfiant envers les autres composants du réseau et demande systématiquement une authentification.

La sécurité des échanges de données doit fournir 4 garanties:

  1. être sûr de son interlocuteur. C'est l'authentification réciproque des correspondants ou des composants.
  2. être sûr que les données transmises n'ont pas été modifiées accidentellement ou intentionnellement. C'est l'intégrité des données.
  3. éviter que les données soient lues par des systèmes ou des personnes non autorisées. C'est la confidentialité.
  4. éviter la contestation par l'émetteur de l'envoi des données. C'est la signature, appelée aussi non répudiation.

Comment obtenir ces 4 garanties dans une architecture REST ?

Avec REST et les URI logiques, il devient très facile de mettre en place un système de contrôle d'accès aux ressources. Dans l'exemple ci-dessus de Yahoo groupes, toutes les URI d'accès aux ressources d'un groupe commencent par /group/exemple_rest/ . Il suffit au niveau du filtre de transformation URI logique/URI physique de vérifier que l'utilisateur ou son agent est bien autorisé à accéder au groupe exemple_rest. S'il ne l'est pas, le filtre redirige la requête vers le module d'authentification et, selon la réponse, autorise ou non l'accès. Cette méthode présente les avantages suivants :

  • indépendance totale entre autorisations et applications (couplage lâche)
  • Point d'entrée unique permettant de créer facilement logs et audits.
  • Granularité des autorisations possible du niveau le plus global au niveau le plus détaillé, l'ensemble des informations nécessaires étant disponibles dans l'URI logique et la méthode HTTP utilisée.

La version HTTPS du protocole HTTP permet d'authentifier le serveur et de chiffrer les données transmises entre le serveur et un agent utilisateur. L'agent utilisateur peut être authentifié par tous les moyens habituels (nom/mot de passe, certificat, biométrie,...).  Ceci permet de traiter de manière sûre le point 1 de la sécurité mentionné plus haut : l'authentification des correspondants. Le point 2 et le point 3 (intégrité et confidentialité) sont obtenus par le chiffrement HTTPS. Le point 4 (signature) est obtenu par l'utilisation de certificats par les utilisateurs. Un très haut niveau de sécurité est donc facilement mis en place sur une architecture REST sans complexité supplémentaire.

Les avantages d'une architecture SOA - REST

Plus on déploie de systèmes informatiques, plus il semble indispensable de réutiliser les fonctions des systèmes existants au lieu de tout reconstruire à partir de zéro. SOA est un style d'architecture dont l'objectif premier est de fournir un couplage lâche entre les agents logiciels. Il simplifie donc la réutilisation.

Pour mieux comprendre, prenons un exemple avec une SOA que vous trouvez dans votre salon. Pour lire un CD, vous utilisez un lecteur CD de salon qui vous offre un service de lecture de CD. Vous pouvez remplacer le lecteur de salon par un lecteur portable qui offre aussi un service de lecture de CD mais avec une qualité de service différente. Vous pouvez aussi choisir de lire un autre CD. Dans la mesure où l'interface entre le CD et le lecteur de CD est bien définie, vous pourrez lire n'importe quel CD sur n'importe quel lecteur.

Cette notion SOA est très différente de la conception objet habituelle. La programmation objet force à regrouper données et traitements. Dans un monde objet, chaque CD vient avec son propre lecteur de CD. Ca peut sembler bizarre, mais c'est comme cela que sont construits la plupart des systèmes actuels. Il est donc évident que dans ces conditions la réutilisation est très limitée.

Le style SOA pousse donc à la réutilisation de services existants avec comme conséquence la nécessité de bien définir des standards de données. Très rapidement on constate qu'il est souvent plus avantageux d'utiliser des services que de les développer. Par exemple dans mon site Web, la fonction recherche est assurée par des professionnels de la recherche (Google) qui permet de limiter les résultats à un domaine particulier figer.com en l'espèce. Je n'ai rien développé et j'utilise le meilleur et le plus rapide service de recherche au monde.

D'autres avantages du style architectural REST découlent de sa simplicité et de son universalité. Le mécanisme HTTP/URI pour le nommage et pour l'accès est universel. L'infrastructure nécessaire pour une architecture REST comme le réseau IP ou les DNS (services de nommage) est déjà en place. Il n'y a donc rien à déployer. Il est souvent surprenant de voir les efforts démesurés faits par des entreprises pour déployer à grands frais une infrastructure propriétaire pour une application alors qu'il suffirait d'utiliser l'infrastructure du web.

L'obligation pour les services d'être sans état [stateless] entraîne deux conséquences intéressantes, l'extensibilité linéaire des services et la tolérance aux pannes :

  • L'extensibilité linéaire des services.
    Chaque requêtes contient toutes les informations nécessaires au service pour la traiter. La performance du service ne dépend plus du nombre d'utilisateurs mais seulement du nombre de transactions par seconde. Ce qui fonctionne pour un utilisateur fonctionnera de la même manière pour plusieurs centaines de millions ! Si le débit en transactions/seconde n'est pas suffisant, alors il suffit de faire du partage de charge avec plusieurs machines équipées du même service. Il n'y a pas une ligne de code à changer dans le logiciel. L'extensibilité est donc parfaitement linéaire.
  • La tolérance aux pannes.
    Comme le service ne conserve pas d'état, une défaillance d'une machine n'entraîne pas de perte d'information. Il suffit de relancer la demande sans réponse pour obtenir le résultat fournit par la même machine ou par une autre si on travaille en partage de charge. Si la panne et le redémarrage ont lieu entre deux appels ou si plusieurs machine fournissent le même service, l'utilisateur ne s'aperçoit de rien.

C'est l'ensemble de ces avantages qui expliquent que REST soit rapidement devenu le modèle d'architecture orientée services le plus répandu dans le monde.

SOAP

SOAP (Simple Object Access Protocol) est un mécanisme qui permet d'échanger des messages XML entre applications, principalement en utilisant le protocole HTTP. SOAP a été développé à l'origine pour traverser via HTTP les pare-feux qui bloquaient les appels RPC [Remote Procedure Call] de DCOM ou IIOP.

SOAP-RPC ne respecte pas le style SOA puisque c'est un moyen de véhiculer des interfaces RPC spécifiques d'une application dans un tuyau standard. il faut une connaissance fine du fonctionnement de chaque application pour l'utiliser. Il ne satisfait donc pas à la contrainte n°1 d'une SOA qui est d'être faiblement couplée.

Conscient de ces faiblesses, le W3C a donc défini SOAP 1.2  comme un moyen d'échanger des messages entre des noeuds[node] SOAP, d'un noeud émetteur SOAP vers un noeud récepteur SOAP. Cette version en mode échange de messages respecte le style SOA à condition que le contenu des messages soit informatif, pas prescriptif.

Voici un exemple de message SOAP tiré de SOAP version 1.2 primer du W3C

<?xml version='1.0' ?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"> 
 <env:Header>
  <m:reservation xmlns:m="http://travelcompany.example.org/reservation" 
          env:role="http://www.w3.org/2003/05/soap-envelope/role/next"
           env:mustUnderstand="true">
   <m:reference>uuid:093a2da1-q345-739r-ba5d-pqff98fe8j7d</m:reference>
   <m:dateAndTime>2001-11-29T13:20:00.000-05:00</m:dateAndTime>
  </m:reservation>
  <n:passenger xmlns:n="http://mycompany.example.com/employees"
          env:role="http://www.w3.org/2003/05/soap-envelope/role/next"
           env:mustUnderstand="true">
   <n:name>Åke Jógvan Øyvind</n:name>
  </n:passenger>
 </env:Header>

 <env:Body>
  <p:itinerary
    xmlns:p="http://travelcompany.example.org/reservation/travel">
   <p:departure>
     <p:departing>New York</p:departing>
     <p:arriving>Los Angeles</p:arriving>
     <p:departureDate>2001-12-14</p:departureDate>
     <p:departureTime>late afternoon</p:departureTime>
     <p:seatPreference>aisle</p:seatPreference>
   </p:departure>
   <p:return>
     <p:departing>Los Angeles</p:departing>
     <p:arriving>New York</p:arriving>
     <p:departureDate>2001-12-20</p:departureDate>
     <p:departureTime>mid-morning</p:departureTime>
     <p:seatPreference/>
   </p:return>
  </p:itinerary>
  <q:lodging
   xmlns:q="http://travelcompany.example.org/reservation/hotels">
   <q:preference>none</q:preference>
  </q:lodging>
 </env:Body>
</env:Envelope>
Exemple de message SOAP pour une réservation de voyage.

Les éléments d'un message SOAP sont donc une enveloppe (env:Envelope), un en-tête (env:Header) et un corps de message (env:Body).

Structure de message SOAP

L'élément Header est optionnel. C'est un moyen de transmettre des informations qui ne font pas partie des données de l'application. Ces informations seront éventuellement traitées par les noeuds SOAP. L'élément Body est le seul élément obligatoire. Il contient les informations qui seront transmises de bout en bout.

En résumé, les différents éléments d'un message SOAP peuvent être représentés de la manière visuelle indiquée dans le dessin à droite.

Les messages SOAP peuvent être échangés entre des noeuds SOAP par une grande variété de protocoles. Cependant dans la majorité des cas, c'est le protocole HTTP qui est utilisé. Un noeud SOAP est donc identifié par son URI comme une ressource en REST. Les premières versions de SOAP imposaient l'usage de POST. La mise en oeuvre de SOAP était donc assez lourde. SOAP ne permettait pas de bénéficier du mécanisme de cache fournit automatiquement par GET. Cette lacune a été comblée dans la version 1.2 de SOAP où la notion de SOAP Web Method a été introduite. Celle-ci permet d'utiliser les verbes HTTP autres que POST comme GET, PUT et DELETE.  

 

WSDL, la documentation des Web services

WSDL[Web Services Description Language] est un langage de description de services Web. C'est un document XML qui permet de décrire chaque service SOAP sous la forme d'une documentation en ligne. Ce document décrit les messages échangés, habituellement sous la forme d'un schéma XML, ainsi que les détails des interfaces publiques de ce service.

Un document WSDL est donc un simple document XML avec quatre éléments principaux <portType>, <message, <type>, <binding> :

  • <portType> définit le service web, les opérations qui peuvent être effectuées et les messages. C'est l'équivalent d'un nom de fonction classique;
  • <message> définit les données de chaque opération. C'est l'équivalent des paramètres d'une fonction classique;
  • <type> définit les types de données en utilisant la notation des schémas XML;
  • <binding> définit le format des messages et les détails du protocole de chaque port.

Cette documentation n'est pas réservée à SOAP. Elle est disponible en ligne. Elle permet de simplifier l'utilisation des services car elle est exploitable directement par les outils de développement ou de programmation.

  

SOAP ou REST pour les web services ?

L'introduction de la spécification Web Method dans SOAP 1.2 permet à SOAP de se conformer au style REST. Cette faiblesse de SOAP ayant été comblée, le débat sur la différence entre ces deux approches est donc devenu en partie sans objet.

Dans les 2 cas, les données sont échangées sous la forme de XML sur HTTP. Il n'y a donc pas, de ce point de vue, de différence en terme de performance ou de fiabilité contrairement aux affirmations de certains vendeurs SOAP. Le fait d'ajouter une enveloppe SOAP autour des données est neutre. Qui d'ailleurs se sert de cette enveloppe ?

La plupart des grands sites qui offrent des services web aux développeurs comme Amazon ou eBay offrent simultanément les deux types d'interfaces. L'écrasante majorité (plus de 85%) des centaines de milliers de développeurs choisissent REST comme interface, essentiellement pour des raisons de simplicité. La barre adresse d'un navigateur suffit pour écrire et tester une requête REST alors que SOAP impose l'emploi d'un langage de programmation et de l'infrastructure correspondante. Ces sites ont par ailleurs unifié les données manipulées par les services SOAP ou REST, ce qui réduit encore l'écart qui aurait pu exister.

La plus grande différence entre les deux styles est le nom de la ressource. Dans le style REST, le nom de la ressource est dans l'URI alors que dans le style SOAP, tous les messages sont généralement envoyés vers point d'entrée unique. Le nom de la fonction à effectuer est caché à l'intérieur de l'enveloppe. Cette manière de faire peut présenter des avantages dans certains cas, en particulier quand certaines parties du message doivent rester confidentielles. En revanche, dans la majorité des cas, c'est plutôt un inconvénient. Le point d'entrée unique entraîne un couplage fort qui complique la gestion des priorités et des performances. Le mécanisme simple décrit précédemment pour assurer la sécurité d'accès ne peut plus être mis en oeuvre. Avec SOAP, la sécurité redevient donc fortement couplée avec l'application.

Ma recommandation est donc la suivante : utiliser le style REST comme style d'architecture majeur et ajouter des interfaces SOAP si nécessaire pour l'interopérabilité avec du SOAP existant par ailleurs.

Le travail de l'architecte ou comment appliquer le style SOA.

Un service d'une architecture orientée service se définit par son URI et par la représentation XML d'un message ou d'une ressource. Ces éléments n'ont pas d'adhérence avec une technologie particulière. Ils doivent être définis par l'architecte. Voici une check-list qu'il faudra personnaliser selon l'environnement.

  • Le premier travail de l'architecte consiste à identifier et à nommer par des URI les ressources persistantes. Une ressource persistante a une durée de vie supérieure à celle d'une transaction ou d'une session. En aucun cas un URI ne doit être la conséquence d'un développement.
  • Il faut bien sûr préférer un nommage logique à un nommage physique des URI pour masquer une implémentation spécifique. Sous Apache, il existe un module mod_rewrite qui permet de manière transparente de rediriger une URL vers une autre. Sous IIS, c'est un peu plus compliqué car il n'y a rien en standard. On peut soit écrire un filtre ISAPI, soit utiliser un composant d'une tierce partie.
  •  Il faut noter que l'URI logique ne contient pas d'indication sur la manière dont chaque service élabore ses réponses. C'est ce qu'on appelle un couplage lâche [loosely coupled]. C'est un principe général d'architecture des systèmes informatiques trop souvent oublié qui devient "naturel" avec SOA.
  • Les ressources doivent être identifiées par des noms, pas par des verbes. Les ressources représentent des états, pas des actions. C'est d'ailleurs la grande différence avec des techniques du type RPC ou Objet qui détaillent à l'infini des actions (méthodes).
  • Les URI ne doivent pas changer car vous ne saurez jamais qui détient des vieilles références : liens dans d'autres pages, utilisateurs dans leurs favoris, notes sur un bout de papier.
  • Le contenu des bases de données ou les entités métiers doivent avoir des URI. Tout navigateur devient un client du pauvre très utile pour les tests. Les références peuvent se trouver dans d’autres médias comme des messages électroniques ou de la documentation. Le XSLT devient utilisable pour présenter, inclure ou transformer les données.
  • La toute puissance du HTTP GET et de la représentation hypermédia permet grâce à des liens de construire la navigation ou de fournir progressivement des détails. L'état d'une application est donné par son URI.
  •  C'est le client qui tire les représentations des ressources. Chaque requête doit comporter toutes les indications nécessaires pour son exécution  et ne doit pas s'appuyer sur un contexte stocké sur le serveur. Tous les services de l'application doivent donc être sans état [stateless].

    Un exemple traditionnel d'architecture avec services fortement couplés est la validation à deux phases [two-phase commit]. Sans-état [Stateless] est un principe d'architecture qui DOIT être respecté pour rester sûr, simple, performant et extensible [scalable].  Il est toujours possible d'éviter la validation à deux phases par des servcies asynchrones avec une gestion des exceptions..

  • La représentation des données doit s'appuyer sur des standards comme utf-8 pour le jeu de caractères, le XML pour la syntaxe des documents et des vocabulaires spécifiques (Dublin Core, RSS, Atom...) pour la sémantique des données. C'est le rôle de l'architecte de bien spécifier tous les standards de l'application.

Conclusion

Le style d'architecture SOA défini par un couplage lâche, des services sans état et hautement interopérables, n'est pas une nouveauté en soi. Ces principes sont recommandés depuis les débuts de l'informatique. ce qui a changé, c'est le contexte. Avec Internet on accède facilement à tous les services où qu'ils soient dans le monde. L'URI associé au DNS (Domain Name System) fournit gratuitement une infrastructure de nommage et d'adressage mondial dont le coût de déploiement n'est pas à la portée d'une entreprise quelle que soit sa taille. Le XML définit une syntaxe unique pour tous les documents, associée au codage Unicode utf-8 permet de représenter l'ensemble des alphabets dans le monde. Aujourd'hui, l'interopérabilité des services, c'est à dire leur interconnexion sans programmation spécifique, ne dépend plus que de l'adoption de vocabulaires de données standards ce qui est en bonne voie dans de nombreux domaines. Dans ce contexte, le style SOA est une obligation. Les sociétés qui ont des centaines de millions d'utilisateurs ont bien compris l'enjeu et fournissent déjà une large gamme de services aux centaines de milliers de développeurs qui interconnectent leurs applications. En revanche, l'offre des vendeurs de produits n'a, en général,  de SOA que le nom. Middleware avec état, non extensible avec débauche de matériel, nommage et adressage local, services fortement couplés. Ce n'est pas quelques connecteurs SOAP qui peuvent modifier l'architecture d'un produit. Il faudra donc attendre beaucoup plus longtemps pour que cette révolution pénètre dans les grandes entreprises.

Envoyer vos remarques, suggestions ou questions à

Jean-Paul Figer
© Jean-Paul Figer, 1958-2013

J'ai travaillé pendant 40 ans à Capgemini. Cependant les opinions exprimées dans ces articles n'engagent que moi et ne représentent pas la position de Capgemini.

Pour être informé des nouveaux articles, inscrivez-vous avec votre adresse mail

Exemples d'utilisation de REST et de SOAP

Tous les sites qui ont un grand succès sur l'Internet offrent des interfaces (APIs) pour intégrer les fonctions de ces sites dans des applications ou des serveurs externes.

  • Google offre une impressionnante liste d'APIs pour utiliser ses services en REST ou en SOAP.
  • Yahoo, avec son "developer network" et une notice sur REST propose de nombreuses méthodes pour exploiter ses services par des programmes.
  • Ebay et Amazon sont plus oecuméniques. Ils offrent non seulement REST mais aussi beaucoup d'autres méthodes. Cependant 85% de leurs utilisateurs choisissent REST.
  • Voici un exemple de recherche avec Yahoo qui renvoie un fichier XML des résultats. J'ai limité le nombre de résultats à 3 sur les plus de 300 000 trouvés.
  • Voici un autre exemple de création de code barre à la demande qui utilise le service Web décrit plus haut. Il nécessite l'écriture d'une petite ligne de Javascript.


    code barre
  • Il y a un excellent exemple de documentation de Web services REST et SOAP sur le site eBay

 

 

Définition de services Web, XML, SOA, EAI

Le succès de l'Internet a engendré une pléthore de concepts, de sigles et de promesses dans le domaine de l'architecture des systèmes. Voici quelques définitions simples pour s'y retrouver.

Services Web

Le terme Services Web a été introduit pour indiquer une interaction entre machines sur Internet qui ne nécessite pas d'intervention humaine. Les machines parlent aux machines. La plupart des autres concepts ont été inventés pour "standardiser" ce dialogue.

XML

XML fournit une syntaxe unique pour les données sans adhérence avec un logiciel particulier. XML présente comme HTML la particularité de véhiculer les données ET leur description. Ce "gaspillage" s'est révélé très efficace.  XSLT et CSS permettent de transformer et de présenter les données XML en fonction de leur usage. Plus de détails...

SOA - Service-oriented Architecture

SOA ou Architecture orientée Services est un style d'architecture destiné à fournir un couplage lâche [loose coupling] entre les composants d'un système. Un service est une fonction métier sans état [stateless] qui  accepte des demandes et renvoie des réponses au travers d'un interface bien défini. Les services ne doivent pas dépendre de l'état d'autres fonctions ou services. C'est ce qui permet de les combiner (orchestration) pour obtenir des traitements plus complexes. Il ne suffit pas de découper un système en blocs fonctionnels indépendants pour obtenir une architecture orientée services. Il faut aussi décrire les mécanismes de nommage, d'adressage et d'échange qui permettent ce découplage. Comme exemples réussis de découplage, on peut citer l'émail et le RSS.

  • Dans l'émail, il y a un découplage complet entre le fait d'envoyer un message (son correspondant n'a pas besoin d'être disponible ou en ligne) et la lecture des messages reçus. En revanche, l'adresse émail du  correspondant doit être valide et connue (couplage fort).
  • Dans le RSS, il y a un découplage parfait entre le producteur du canal RSS qui ne fait que la mise à jour de son canal d'information à son rythme et l'utilisateur de données RSS qui exploite les informations du canal à son rythme. Le seul couplage, minimal, est la connaissance de l'URI du canal RSS.

EAI - Enterprise Application Integration

L'EAI est un ensemble d'outils et de méthodes destiné à consolider, moderniser et coordonner les applications existantes dans une entreprise. Trop souvent, ces outils ne font qu'ajouter une couche supplémentaire de logiciels sans diminuer la complexité des systèmes. Le meilleur EAI que je connaisse est tout simplement XML+HTTP.

Ressource et Objet

Au début des années 1990, la technologie objet était considérée comme la technologie la plus prometteuse pour écrire du logiciel.  Force est de constater que quinze ans plus tard, cette technologie n'a pas apporté ce que l'on en attendait. Ce qui fonctionnait très bien localement dans une seule machine  n'a pas supporté le "passage à l'échelle". La communication inter programmes avec des objets distribués comme RMI, CORBA ou DCOM a été un échec sérieux.

Bien que les ressources ressemblent à des objets, en particulier pour les propriétés, il y a beaucoup de différences. La plus grosse différence est liée au nombre de méthodes. La programmation objet a tendance à multiplier les méthodes ce qui augmente la complexité des interfaces alors que REST utilise seulement 2 méthodes principales, GET et POST. En revanche, le style REST a tendance à multiplier les URI des ressources. Cependant, c'est L'URI associé à HTTP GET permet de réduire l'adhérence entre les composants à un minimum.