SOAP : Simple Object Access Protocol

Auteurs

Don Box, DevelopMentor, David Ehnebuske, IBM, Gopal Kakivaya, Microsoft, Andrew Layman, Microsoft, Noah Mendelsohn, Lotus Development Corp., Henrik Frystyk Nielsen, Microsoft, Satish Thatte, Microsoft, Dave Winer, UserLand Software, Inc.

Copyright 2000 DevelopMentorSite en anglais, International Business Machines Corporation, Lotus Development Corporation, Microsoft, UserLand SoftwareSite en anglais

Résumé

SOAP est un protocole léger permettant d'échanger des informations dans un environnement décentralisé et distribué. Basé sur le protocole XML, il est constitué de trois parties : une enveloppe qui définit un cadre de description du contenu des messages et du mode de traitement à utiliser, un ensemble de règles de codage pour exprimer les instances de types de données définis par l'application et une convention de représentation des appels de procédure et des réponses à distance. SOAP peut être associé à d'autres protocoles. Toutefois, seules les liaisons décrites dans ce document permettent d'utiliser SOAP en association avec HTTP et la structure d'extension HTTP.

Table des matières

1. Introduction
1.1 Objectifs de conception
1.2 Conventions de notation
1.3 Exemples de messages SOAP
2. Le modèle d'échange de messages de SOAP
3. Relation avec XML
4. Enveloppe SOAP
4.1.1 Attribut encodingStyle de SOAP
4.1.2 Les versions d'enveloppe
4.2 En-tête SOAP
4.2.1 Utilisation des attributs d'en-tête
4.2.2 Attribut acteur de SOAP
4.2.3 Attribut mustUnderstand de SOAP
4.3 Corps SOAP
4.3.1 Relation entre l'en-tête et le corps SOAP
4.4 Erreur SOAP
4.4.1 Codes d'erreur SOAP
5. Codage SOAP
5.1 Règles pour les types de codage dans XML
5.2 Types simples
5.2.1 Chaînes
5.2.2 Énumérations
5.2.3 Tableau d'octets
5.3 Accessoire polymorphe
5.4 Types composés
5.4.1 Valeurs composées, structs et références à ces valeurs
5.4.2 Tableaux
5.4.2.1 Tableaux partiellement transmis
5.4.2.2 Tableaux fragmentés
5.4.3 Types composés génériques
5.5 Valeurs par défaut
5.6 Attribut racine de SOAP
6. Utilisation de SOAP dans HTTP
6.1 Requête SOAP HTTP
6.1.1 Le champ d'en-tête HTTP SOAPAction
6.2 Réponse SOAP HTTP
6.3 La structure d'extension HTTP
6.4 Exemples SOAP HTTP
7. Utilisation de SOAP pour les appels de procédure à distance (RPC)
7.1 Appels de procédure à distance (RPC) et corps SOAP
7.2 Appels de procédure à distance et en-tête SOAP
8. Questions de sécurité
9. Références
A. Exemples d'enveloppe SOAP
A.1 Exemple de codage des requêtes d'appel
A.2 Exemple de codage d'une réponse


1. Introduction

SOAP offre un moyen simple et léger d'échanger des informations structurées et typées entre pairs dans un environnement décentralisé et distribué utilisant XML. SOAP ne définit pas lui-même la sémantique d'une application, comme le modèle de programmation ou la sémantique spécifique à l'implémentation. Il définit plutôt un mécanisme simple d'expression de la sémantique de l'application en proposant un modèle d'empaquetage modulaire et des mécanismes de codage des données dans des modules. Cela permet d'utiliser SOAP dans un grand nombre de systèmes allant des systèmes de messagerie aux appels de procédure à distance (RPC).

SOAP est constitué de trois parties :

  • La structure de l'enveloppe SOAP (voir section 4) définit une structure générale pour exprimer le contenu d'un message, le responsable de son traitement et le caractère facultatif ou obligatoire de ce message.
  • Les règles de codage de SOAP (voir section 5) définissent un mécanisme de sérialisation qui peut être utilisé pour échanger des instances de types de données définis par l'application.
  • La représentation RPC de SOAP (voir section 7) définit une convention qui peut être utilisée pour représenter les appels de procédures à distance et leurs réponses.

Si ces éléments sont décrits comme faisant partie de SOAP, ils sont orthogonaux d'un point de vue fonctionnel. L'enveloppe et les règles de codage, en particulier, sont définies dans des espaces de noms différents pour faciliter le fonctionnement grâce à une plus grande modularité.

Outre une enveloppe, des règles de codage et des conventions RPC, SOAP définit deux liaisons de protocoles qui décrivent comment un message SOAP peut être véhiculé dans des messages HTTP [5] avec ou sans structure d'extension HTTP [6].

1.1 Objectifs de conception

Le principal objectif de conception de SOAP est la simplicité et l'extensibilité. C'est pourquoi diverses fonctionnalités des systèmes de messagerie et des systèmes distribués objet traditionnels ne font pas partie de la spécification principale de SOAP :

  • Nettoyage de mémoire distribué
  • Empaquetage ou mise en lots des messages
  • Objets par référence (ce qui requiert un nettoyage de mémoire distribué)
  • Activation (ce qui requiert des objets par référence)

1.2 Conventions de notation

Les mots clés "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMANDED", "MAY" et "OPTIONAL" présents dans ce document doivent être interprétés comme indiqué dans RFC-2119 [2].

Les préfixes d'espaces de noms "SOAP-ENV" et "SOAP-ENC" utilisés dans ce document sont respectivement associés aux espaces de noms SOAP "http://schemas.xmlsoap.org/soap/envelope/" (en anglais) et "http://schemas.xmlsoap.org/soap/encoding/" (en anglais).

Dans l'ensemble de ce document, le préfixe d'espace de noms "xsi" est supposé être associé à l'URI "http://www.w3.org/1999/XMLSchema-instance" (en anglais) qui est défini dans la spécification des schémas XML [11]. De même, le préfixe d'espace de noms "xsd" est supposé être associé à l'URI "http://www.w3.org/1999/XMLSchema" (en anglais) qui est défini dans [10]. Le préfixe d'espace de noms "tns" est utilisé pour indiquer l'espace de noms cible du document en cours. Tous les autres préfixes d'espaces de noms ne sont que des exemples.

Les URI d'espaces de noms de forme générale "some-URI" représentent des URI dépendants de l'application ou du contexte [4].

Cette spécification utilise le BNF (Backus-Naur Form) tel que décrit dans RFC-2616 [5] pour certaines structures.

1.3 Exemples de messages SOAP

Dans cet exemple, une requête SOAP GetLastTradePrice est envoyée à un service StockQuote. Le requête prend un paramètre de chaîne, le sigle de l'action, puis renvoie un flottant dans la réponse SOAP. L'élément Enveloppe SOAP est le premier élément du document XML représentant le message SOAP. Les espaces de noms XML sont utilisés pour différencier les identificateurs SOAP des identificateurs spécifiques à l'application. L'exemple illustre les liaisons HTTP définies à la section 6. Remarquez que les règles régissant le format de charge utile XML dans SOAP sont tout à fait indépendantes du fait que la charge utile soit véhiculée dans HTTP.

D'autres exemples sont disponibles en Annexe A.

Exemple 1 : Message SOAP incorporé dans une requête HTTP

POST /StockQuote HTTP/1.1
Host: 
www.stockquoteserver.com
Content-Type: text/xml; 
charset="utf-8"
Content-Length: nnnn
SOAPAction: 
"Some-URI"

<SOAP-ENV:Envelope
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
 <SOAP-ENV:Body>
 <m:GetLastTradePrice xmlns:m="Some-URI">
 <symbol>DIS</symbol>
 </m:GetLastTradePrice>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

L'exemple suivant montre le message de réponse contenant le message HTTP avec le message SOAP en tant que charge utile :

Example 2 : Message SOAP incorporé dans une réponse HTTP

HTTP/1.1 200 OK
Content-Type: text/xml; 
charset="utf-8"
Content-Length: 
nnnn

<SOAP-ENV:Envelope
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
 <SOAP-ENV:Body>
 <m:GetLastTradePriceResponse xmlns:m="Some-URI">
 <Price>34,5</Price>
 </m:GetLastTradePriceResponse>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

2. Le modèle d'échange de messages de SOAP

Les messages SOAP sont avant tout des transmissions unidirectionnelles envoyées par un expéditeur à un destinataire. Mais, comme cela est illustré ci-dessus, les messages SOAP sont souvent associés pour implémenter des modèles de type requête/réponse.

Les implémentations SOAP peuvent être optimisées pour exploiter les caractéristiques particulières de systèmes de réseau donnés. Par exemple, la liaison HTTP décrite à la section 6 permet de délivrer les messages de réponse SOAP comme des réponses HTTP, en utilisant la même connection que la requête entrante.

Quel que soit le protocole auquel SOAP est lié, les messages sont acheminés via un "chemin de message", qui permet d'effectuer le traitement sur un ou plusieurs nœuds intermédiaires, ainsi que sur la destination finale.

Une application SOAP recevant un message SOAP DOIT ABSOLUMENT traiter ce message en respectant les étapes suivantes, dans l'ordre :

  1. Identifier toutes les parties du message SOAP destinées à cette application (voir section 4.2.2)
  2. Vérifier que toutes les parties obligatoires identifiées lors de l'étape 1 sont prises en charge par l'application pour ce message (voir section 4.2.3) et les traiter en conséquence. Si elles ne sont pas prises en charge, ignorer le message (voir section 4.4). Le processeur PEUT ignorer les parties facultatives identifiées lors de l'étape 1 sans que cela n'affecte le résultat du traitement.
  3. Si l'application SOAP n'est pas l'ultime destination du message, supprimer toutes les parties identifiées lors de l'étape 1 avant de transférer le message.

Pour traiter un message ou une partie d'un message, le processeur SOAP doit comprendre, entre autres, le modèle d'échange utilisé (unidirectionnel, requête/réponse, multidiffusion, etc.), le rôle du destinataire dans ce modèle, l'utilisation (le cas échéant) de mécanismes RPC comme celui présenté à la section 7, la représentation ou le codage des données, ainsi que toute autre sémantique nécessaire au bon traitement.

Si des attributs tels que l'attribut encodingStyle de SOAP (voir section 4.1.1) peuvent être utilisés pour décrire certains aspects d'un message, cette spécification n'oblige pas le destinataire à utiliser un moyen particulier pour faire de telles descriptions. Par exemple, certaines applications comprendront qu'un élément <getStockPrice> donné signale une requête RPC en utilisant les conventions de la section 7, alors qu'une autre application peut déduire que toutes transmissions dirigées vers elle sont codées comme des messages à sens unique.

3. Relation avec XML

Tous les messages SOAP sont codés à l'aide de XML (voir [7] pour davantage d'informations sur XML).

Une application SOAP DEVRA (SHOULD) inclure l'espace de noms SOAP qui convient sur tous les éléments et les attributs définis par SOAP dans les messages générés. Une application SOAP DOIT ABSOLUMENT (MUST) être capable de traiter les espaces de noms SOAP dans les messages qu'elle reçoit. Elle DOIT ABSOLUMENT ignorer les messages qui contiennent des espaces de noms incorrects (voir section 4.4) et PEUT (MAY) traiter les messages SOAP sans espaces de noms comme s'ils comportaient des espaces de noms SOAP corrects.

SOAP définit deux espaces de noms (voir [8] pour davantage d'informations sur les espaces de noms XML) :

Un message SOAP NE DOIT ABSOLUMENT PAS (MUST NOT) contenir de déclaration de type de document. Un message SOAP NE DOIT ABSOLUMENT PAS contenir d'instructions de traitement. [7]

SOAP utilise l'attribut local non qualifié "id" de type "ID" pour spécifier l'identificateur unique d'un élément codé. SOAP utilise l'attribut local non qualifié "href" de type "uri-reference" pour spécifier une référence à cette valeur, conformément à la spécification XML [7], la spécification de schéma XML [11] et la spécification de langage de liaison XML [9].

Exception faite de l'attribut mustUnderstand de SOAP (voir section 4.2.3) et de l'attribut acteur de SOAP (voir section 4.2.2), il est généralement permis de faire apparaître les attributs et leur valeur dans les instances XML ou bien dans les schémas, avec les mêmes effets. C'est-à-dire qu'une déclaration dans une DTD ou dans un schéma avec une valeur par défaut ou déterminée est, d'un point de vue sémantique, équivalente à une déclaration dans une instance.

4. Enveloppe SOAP

Un message SOAP est un document XML constitué d'une enveloppe SOAP obligatoire, d'un en-tête SOAP facultatif et d'un corps SOAP obligatoire. Ce document XML sera appelé message SOAP dans le reste de cette spécification. L'identificateur d'espace de noms pour les éléments et les attributs définis dans cette section est "http://schemas.xmlsoap.org/soap/envelope/" (en anglais). Un message SOAP contient les éléments suivants :

  • L'élément Envelope est le premier élément du document XML représentant le message.
  • L'élément Header (en-tête) est un mécanisme générique permettant d'ajouter des fonctions à un message SOAP de façon décentralisée sans accord préalable entre les parties en communication. SOAP définit quelques attributs qui peuvent être utilisés pour indiquer qui doit gérer cette fonctionnalité et si cette fonctionnalité est facultative ou obligatoire (voir section 4.2).
  • L'élément Body (Corps) contient les informations obligatoires destinées à l'ultime destinataire du message (voir section 4.3). SOAP définit un élément pour le corps, qui est l'élément Fault (Erreur) utilisé pour rapporter les erreurs.

Les règles grammaticales sont les suivantes :

  1. Enveloppe
    • Le nom de l'élément est "Envelope".
    • L'élément DOIT ABSOLUMENT être présent dans un message SOAP.
    • L'élément PEUT contenir des déclarations d'espace de noms ainsi que des attributs supplémentaires. Ces attributs supplémentaires, s'ils existent, DOIVENT ABSOLUMENT être rattachés à un espace de noms. De même, l'élément PEUT contenir des sous-éléments supplémentaires. S'ils existent, ces éléments DOIVENT ABSOLUMENT être rattachés à un espace de noms et DOIVENT ABSOLUMENT suivre l'élément Body de SOAP.
  2. En-tête (voir section 4.2)
    • Le nom de l'élément est "Header".
    • L'élément PEUT être présent dans un message SOAP. S'il est présent, l'élément DOIT ABSOLUMENT être le premier enfant direct d'un élément Envelope SOAP.
    • L'élément PEUT contenir un jeu d'entrées d'en-tête, chaque entrée étant un enfant direct de l'élément Header de SOAP. Tous les enfants directs de l'élément Header de SOAP DOIVENT ABSOLUMENT être rattachés à un espace de noms.
  3. Corps (voir section 4.3)
    • Le nom de l'élément est "Body".
    • L'élément DOIT ABSOLUMENT être présent dans un message SOAP et DOIT ABSOLUMENT être un enfant direct d'un élément Envelope de SOAP. Il DOIT ABSOLUMENT suivre directement l'élément Header de SOAP, s'il existe. Sinon, il DOIT ABSOLUMENT être le premier enfant direct de l'élément Envelope de SOAP.
    • L'élément PEUT contenir un jeu d'entrées de corps, chaque entrée étant un enfant direct de l'élément Body de SOAP. Les enfants directs de l'élément Body de SOAP PEUVENT être rattachés à un espace de noms. SOAP définit l'élément Fault de SOAP, qui est utilisé pour indiquer les messages d'erreur (voir section 4.4).

4.1.1 Attribut encodingStyle de SOAP

L'attribut global encodingStyle de SOAP peut être utilisé pour indiquer les règles de sérialisation utilisées dans un message SOAP. Cet attribut PEUT apparaître sur tout élément et s'applique au contenu de cet élément et à tous les éléments enfants qui ne contiennent pas eux-mêmes cet attribut, tout comme peut être étendue une déclaration d'espace de noms XML. Aucun codage par défaut n'est défini pour un message SOAP.

La valeur de l'attribut est une liste ordonnée d'un ou plusieurs URI identifiant la ou les règles de sérialisation qui peuvent être utilisées pour désérialiser le message SOAP. Elles sont indiquées par ordre décroissant de spécificité (de la plus spécifique à la moins spécifique). Voici quelques exemples de valeurs :

 "http://schemas.xmlsoap.org/soap/encoding/"
 (en anglais) "http://mon.hôte/encoding/restricted" "http://mon.hôte/encoding/"
""

Les règles de sérialisation définies par SOAP à la section 5 sont identifiées par l'URI "http://schemas.xmlsoap.org/soap/encoding/" (en anglais). Les messages utilisant cette sérialisation DEVRONT l'indiquer en utilisant l'attribut encodingStyle de SOAP. De plus, tous les URI dont la syntaxe commence par "http://schemas.xmlsoap.org/soap/encoding/" (en anglais) indiquent leur conformité avec les règles de codage SOAP définies à la section 5 (même si des règles plus strictes peuvent avoir été ajoutées).

Un URI vide ("") indique explicitement qu'aucune demande n'est formulée pour le style de codage des éléments contenus. Cela peut être utilisé pour désactiver les demandes provenant des éléments contenants.

4.1.2 Les versions d'enveloppe

SOAP ne fonctionne pas selon le modèle habituel d'incrémentation ou de décrémentation des numéros de versions. Un message SOAP DOIT ABSOLUMENT avoir un élément Envelope associé à l'espace de noms "http://schemas.xmlsoap.org/soap/envelope/" (en anglais). Si une application SOAP reçoit un message dont l'élément Envelope de SOAP est associé à un espace de noms différent, l'application DOIT ABSOLUMENT signaler une erreur de version et ignorer le message. Si le message est reçu via un protocole requête/réponse comme HTTP, l'application DOIT ABSOLUMENT répondre par un message de code d'erreur VersionMismatch (voir section 4.4) utilisant l'espace de noms SOAP "http://schemas.xmlsoap.org/soap/envelope/".

4.2 En-tête SOAP

SOAP offre un mécanisme flexible pour étendre un message de façon décentralisée et modulaire sans connaître au préalable les parties en communication. Les extensions que l'on implémente le plus souvent sous forme d'entrées d'en-tête sont des données d'authentification, de gestion des transactions, de paiement, etc.

L'élément Header est codé comme premier enfant direct de l'élément XML Envelope de SOAP. Tous les enfants directs de l'élément Header sont appelées des entrées d'en-tête.

Les règles de codages des entrées d'en-tête sont les suivantes :

  1. Toute entrée d'en-tête est identifiée par son nom d'élément complet, composé de l'URI de l'espace de noms et du nom local. Tous les enfants directs de l'élément Header DOIVENT ABSOLUMENT être rattachés à un espace de noms.
  2. L'attribut encodingStyle PEUT être utilisé pour indiquer le style de codage utilisé pour les entrées d'en-tête (voir section 4.1.1).
  3. L'attribut mustUnderstand (voir section 4.2.3) et l'attribut acteur de SOAP (voir section 4.2.2) PEUVENT être utilisés pour indiquer qui doit traiter l'entrée et de quelle façon (voir section 4.2.1).

4.2.1 Utilisation des attributs d'en-tête

Les attributs de l'élément Header de SOAP définis dans cette section déterminent comment le destinataire d'un message SOAP doit traiter le message comme indiqué à la section 2. Une application SOAP qui génère un message SOAP DEVRA utiliser exclusivement les attributs de l'élément Header de SOAP sur les enfants directs de l'élément Header de SOAP. Le destinataire d'un message SOAP DOIT ABSOLUMENT ignorer tous les attributs de l'élément Header de SOAP qui ne sont pas appliqués à un enfant direct de l'élément Header de SOAP.

Voici un exemple d'en-tête avec un identificateur d'élément "Transaction", une valeur "mustUnderstand" de "1" et une valeur de 5. Le codage serait le suivant :

<SOAP-ENV:Header>
 <t:Transaction
 xmlns:t="some-URI" SOAP-ENV:mustUnderstand="1">
 5
 </t:Transaction>
</SOAP-ENV:Header>

4.2.2 Attribut acteur de SOAP

Un message SOAP voyage de son créateur vers son destinataire ultime, en passant éventuellement par divers intermédiaires SOAP situés sur le chemin du message. Un intermédiaire SOAP est une application capable à la fois de recevoir et de transférer des messages SOAP. Les intermédiaires et le destinataire ultime sont identifiés par un URI.

Il se peut que toutes les parties d'un message SOAP ne soient pas acheminées jusqu'au destinataire ultime du message SOAP, mais soient destinées à un ou à plusieurs intermédiaires situés sur le chemin du message. Le rôle du destinataire d'un élément en-tête est d'accepter un contrat qui ne peut aller au-delà du destinataire. C'est-à-dire qu'un destinataire qui reçoit un élément d'en-tête NE DOIT ABSOLUMENT PAS transférer cet élément d'en-tête à l'application suivante sur le chemin du message SOAP. Le destinataire PEUT insérer un élément d'en-tête similaire mais, dans ce cas, le contrat concerne cette application et le destinataire de cet élément d'en-tête.

L'attribut global acteur de SOAP peut être utilisé pour indiquer le destinataire d'un élément d'en-tête. La valeur de l'attribut acteur de SOAP est un URI. L'URI spécial "http://schemas.xmlsoap.org/soap/actor/next/" indique que l'élément d'en-tête est destiné à la première application SOAP qui traite le message. Cela est semblable au modèle d'étendue tronçon par tronçon représenté par le champ d'en-tête connection dans HTTP.

L'omission de l'attribut acteur de SOAP indique que le destinataire est le destinataire ultime du message SOAP.

Cet attribut DOIT ABSOLUMENT apparaître dans l'instance du message SOAP pour être effectif (voir sections 3 et 4.2.1).

4.2.3 Attribut mustUnderstand de SOAP

L'attribut global mustUnderstand de SOAP peut être utilisé pour indiquer si le traitement d'une entrée d'en-tête par le destinataire est obligatoire ou facultatif. Le destinataire d'une entrée d'en-tête est défini par l'attribut acteur de SOAP (voir section 4.2.2). La valeur de l'attribut mustUnderstand est soit "1" soit "0". L'absence de l'attribut mustUnderstand est sémantiquement équivalente à sa présence avec une valeur "0".

Si un élément d'en-tête est accompagné d'un attribut mustUnderstand SOAP ayant une valeur de "1", le destinataire de cette entrée d'en-tête DOIT ABSOLUMENT obéir à la sémantique (véhiculée par le nom complet de l'élément) et procéder au traitement conformément à cette sémantique ou DOIT ABSOLUMENT déclarer l'échec du traitement du message (voir section 4.4).

L'attribut mustUnderstand de SOAP est le garant d'une bonne évolution. Les éléments accompagnés d'un attribut mustUnderstand ayant une valeur de "1" DOIVENT ABSOLUMENT être envisagés comme modifiant en quelque sorte la sémantique de leurs éléments parents ou pairs. En balisant ainsi les éléments, on garantit que cette modification sémantique ne passe pas inaperçue auprès de ceux qui ne comprennent pas entièrement le processus.

Cet attribut DOIT ABSOLUMENT apparaître dans l'instance pour être effectif (voir sections 3 et 4.2.1).

4.3 Corps SOAP

L'élément Body de SOAP offre un mécanisme simple d'échange des informations obligatoires destinées au destinataire ultime du message. On utilise en général l'élément Body pour organiser les appels RPC et les rapports d'erreurs.

L'élément Body est codé comme enfant direct de l'élément XML Envelope de SOAP. Si un élément Header existe, l'élément Body DOIT ABSOLUMENT suivre immédiatement l'élément Header ou bien DOIT ABSOLUMENT être le premier enfant direct de l'élément Envelope.

Tous les enfants directs de l'élément Body sont appelés des entrées de corps et chaque entrée de corps est codée comme élément indépendant au sein de l'élément Body de SOAP.

Les règles de codage des entrées de corps sont les suivantes :

  1. Toute entrée de corps est identifiée par son nom d'élément complet, composé de l'URI de l'espace de noms et du nom local. Les enfants directs de l'élément Body de SOAP PEUVENT être rattachés à un espace de noms.
  2. L'attribut encodingStyle de SOAP PEUT être utilisé pour indiquer le style de codage utilisé pour les entrées de corps (voir section 4.1.1).

SOAP définit une entrée de corps, qui est l'entrée Fault utilisée pour rapporter les erreurs (voir section 4.4).

4.3.1 Relation entre l'en-tête et le corps SOAP

Bien que le corps et l'en-tête soient définis comme des éléments indépendants, ils sont en fait liés. La relation entre une entrée de corps et une entrée d'en-tête est la suivante : une entrée de corps est sémantiquement équivalente à une entrée d'en-tête destinée à l'acteur par défaut et comportant un attribut mustUnderstand SOAP ayant une valeur de "1". On désigne l'acteur par défaut en n'utilisant pas l'attribut acteur (voir section 4.2.2).

4.4 Erreur SOAP

L'élément Fault de SOAP est utilisé pour véhiculer des informations d'état et/ou d'erreur dans un message SOAP. S'il existe, l'élément Fault de SOAP DOIT ABSOLUMENT apparaître comme entrée de corps et NE DOIT ABSOLUMENT PAS apparaître plus d'une fois dans un même élément Body.

L'élément Fault de SOAP définit les quatre sous-élements suivants :

faultcode
L'élément faultcode est destiné à être utilisé par le logiciel pour fournir un mécanisme algorithmique d'identification de l'erreur. L'élément faultcode DOIT ABSOLUMENT être présent dans un élément Fault de SOAP et sa valeur DOIT ABSOLUMENT être un nom complet comme défini en [8], section 3. SOAP définit un petit nombre de codes d'erreur SOAP qui couvrent les principales erreurs SOAP (voir section 4.4.1)
faultstring
L'élément faultstring fournit une explication de l'erreur dans un format lisible par l'homme et ne sert pas au traitement algorithmique. L'élément faultstring est similaire à "Reason-Phrase" défini par HTTP (voir [5], section 6.1). Il DOIT ABSOLUMENT être présent dans l'élément Fault de SOAP et DEVRA fournir un minimum d'explications sur la nature de l'erreur.
faultactor
L'élément faultactor fournit des informations sur le responsable de l'erreur sur le chemin du message (voir section 2). Il est similaire à l'attribut acteur de SOAP (voir section 4.2.2), mais plutôt que d'indiquer la destination d'une entrée d'en-tête, il indique la source de l'erreur. La valeur de l'attribut faultactor est un URI identifiant la source. Les applications qui n'agissent pas en tant que destinataire ultime du message SOAP DOIVENT ABSOLUMENT comprendre l'élément faultactor dans l'élément Fault de SOAP. Le destinataire ultime d'un message PEUT utiliser l'élément faultactor pour indiquer de façon explicite qu'il a généré l'erreur (voir également l'élément detail ci-dessous).
detail
L'élément detail est destiné à véhiculer des informations d'erreurs spécifiques à une application, liées à l'élément Body. Il DOIT ABSOLUMENT être présent en cas d'échec de traitement du contenu de l'élément Body. Il NE DOIT ABSOLUMENT PAS être utilisé pour véhiculer des informations sur des erreurs appartenant aux entrées d'en-tête. Les informations détaillées sur les erreurs appartenant aux entrées d'en-tête DOIVENT ABSOLUMENT être véhiculées au sein des entrées d'en-tête.

L'absence de l'élément detail dans l'élément Fault indique que l'erreur n'est pas liée au traitement de l'élément Body. Cette indication peut être utilisée pour savoir si l'élément Body a été ou non traité en cas de situation d'erreur.

Tous les enfants directs de l'élément detail sont appelés des entrées de détail et chaque entrée de détail est codée comme un élément indépendant au sein de l'élément detail.

Les règles de codage des entrées de détail sont les suivantes (voir également l'exemple 10) :
  1. Une entrée de détail est identifiée par son nom d'élément complet, composé de l'URI de l'espace de noms et du nom local. Les enfants directs de l'élément detail PEUVENT être rattachés à un espace de noms.
  2. L'attribut encodingStyle de SOAP PEUT être utilisé pour indiquer le style de codage utilisé pour les entrées de détail (voir section 4.1.1).

Il est possible d'introduire d'autres sous-éléments Fault, à condition qu'ils soient rattachés à un espace de noms.

4.4.1 Codes d'erreur SOAP

Les valeurs de l'élément faultcode définies dans cette section DOIVENT ABSOLUMENT être utilisées dans l'élément faultcode pour décrire les erreurs définies par cette spécification. L'identificateur de l'espace de noms pour ces valeurs de faultcode est "http://schemas.xmlsoap.org/soap/envelope/" (en anglais). L'utilisation de cet espace est recommandé (mais pas obligatoire) dans la spécification de méthodes définies en dehors de la présente spécification.

Les valeurs par défaut de faultcode SOAP sont définies de façon extensible afin de permettre la définition de nouvelles valeurs tout en maintenant une compatibilité ascendante avec les valeurs de faultcode existantes. Le mécanisme utilisé est très similaire aux principales classes d'état définies dans HTTP (1xx, 2xx, 3xx, etc., voir [5] section 10). Toutefois, elles ne sont plus définies comme des entiers mais comme des noms qualifiés XML (voir [8] section 3). Le caractère "." (point) est utilisé comme séparateur des valeurs de faultcode et indique que la valeur qui se trouve à sa gauche est une valeur de code d'erreur plus générique que celle se trouvant à sa droite. Exemple :

Client.Authentication

Les valeurs de faultcode définies dans ce document sont les suivantes :

Nom Signification
VersionMismatch La partie chargée du traitement a détecté un espace de noms non valide pour l'élément Envelope de SOAP (voir section 4.1.2)
MustUnderstand Un enfant direct de l'élément Header de SOAP, qui n'a pas été compris ou dont les instructions n'ont pas été respectées par la partie chargée du traitement, contenait un attribut mustUnderstand SOAP avec une valeur de "1" (voir section 4.2.3)
Client La classe d'erreurs Client indique que le message n'a pas été correctement composé ou qu'il ne contenait pas les informations nécessaires à sa bonne transmission. Par exemple, le message ne présentait pas des informations correctes d'authentification ou de paiement. Cela indique généralement que le message n'a pas pu être renvoyé sans modification. Pour une description du sous-élément detail de l'élément Fault de SOAP, veuillez vous reporter également à la section 4.4.
Server La classe d'erreurs Server indique que le message n'a pas pu être traité pour des raisons qui ne sont pas directement attribuables au contenu du message lui-même mais plutôt au traitement du message. Par exemple, le traitement peut exiger une communication avec un processeur en aval et ce dernier n'a pas répondu. Le message pourra être transmis avec succès plus tard. Pour une description du sous-élément detail de l'élément Fault de SOAP, veuillez vous reporter également à la section 4.4.

5. Codage SOAP

Le style de codage de SOAP repose sur un système de types simple qui est une généralisation des fonctionnalités courantes que l'on trouve dans les systèmes de types des langages de programmation, des bases de données et des données semi-structurées. Un type peut être simple (scalaire) ou composé, formant alors un composite constitué de plusieurs parties ayant chacune un type. Ceci est décrit plus en détails ci-dessous. Cette section définit les règles de sérialisation d'un graphique d'objets typés. Le fonctionnement est à deux niveaux. Premièrement, étant donné un schéma dans une notation quelconque, cohérent avec le système de types décrit, un schéma pour une grammaire XML peut être construit. Deuxièmement, étant donné un schéma de système de types et un graphique de valeurs correspondant à ce schéma, une instance XML peut être construite. À l'inverse, étant donné une instance XML produite conformément à ces règles et étant donné également le schéma d'origine, une copie du graphique de valeurs d'origine peut être construite.

L'identificateur de l'espace de noms pour les éléments et les attributs définis dans cette section est "http://schemas.xmlsoap.org/soap/encoding/" (en anglais). Les exemples de codage fournis reposent sur le principe que toutes les déclarations d'espace de noms se situent à un niveau d'élément supérieur.

L'utilisation du modèle de données et du style de codage décrit dans cette section est recommandé mais pas obligatoire ; d'autres modèles de données et codages peuvent être utilisés en association avec SOAP (voir section 4.1.1).

5.1 Règles pour les types de codage dans XML

Avec XML, le codage des données est très flexible. SOAP définit un ensemble de règles de codage plus restreint. Cette section définit les règles de codage de niveau supérieur et la section suivante décrit les règles de codage pour des types spécifiques qui exigent plus de détails. Les codages décrits dans cette section peuvent être utilisés en association avec le mappage d'appels et de réponses de procédures à distance spécifiés à la Section 7.

Pour décrire le codage, on utilisera la terminologie suivante :

  1. Une "valeur" est une chaîne, le nom d'une mesure (numéro, date, énumération, etc.) ou un composé de plusieurs de ces valeurs premières. Toutes les valeurs sont de type spécifique.
  2. Une "valeur simple" est une valeur sans parties nommées. Par exemple, les chaînes, les entiers, les valeurs énumérées, etc., sont des valeurs simples.
  3. Une "valeur composée" est un agrégat de relations vers d'autres valeurs. Par exemple, les commandes fournisseur, les rapports de stocks, les adresses de rues, etc., sont des valeurs composées.
  4. Dans une valeur composée, chaque valeur corrélée peut être différenciée par un nom de rôle et/ou un ordinal. Cela constitue ce que l'on appelle son "accessoire". Les ordres d'achat et les rapports de stocks, mais aussi les tableaux, sont des valeurs composées. Il est possible de trouver des valeurs composées avec plusieurs accessoires ayant le même nom, comme le fait par exemple RDF.
  5. Un "tableau" est une valeur composée dans laquelle la position ordinale est la seule chose qui différencie les valeurs membres.
  6. Un "struct" est une valeur composée dans laquelle le nom de l'accessoire est la seule chose qui différencie les valeurs membres et chaque accessoire a un nom différent.
  7. Un "type simple" est une classe de valeurs simples. Par exemple, les classes appelées "chaîne", "entier", les classes d'énumération, etc., sont des types simples.
  8. Un "type composé" est une classe de valeurs composées. Un type composé peut être par exemple une classe de valeurs d'ordre d'achat partageant les mêmes accessoires (shipTo, totalCost, etc.) même s'ils ont des valeurs potentiellement différentes (et éventuellement soumises à d'autres limites).
  9. Dans un type composé, si un accessoire a un nom différent au sein de ce type mais identique dans d'autres types (c'est-à-dire, s'il est nécessaire de réunir le nom et le type pour parvenir à une identification unique), le nom est dit "local". Si toutefois le nom est basé en partie sur un URI (Uniform Resource Identifier), directement ou indirectement, de telle sorte que le nom seul suffit à identifier l'accessoire sans équivoque quel que soit le type dans lequel il apparaît, le nom est dit "universel".
  10. Au vu des informations du schéma par rapport auquel un graphique de valeurs est sérialisé, il est possible de déterminer que certaines valeurs peuvent uniquement être corrélées par une seule instance d'un accessoire. Pour d'autres valeurs, cette détermination est impossible. Si une valeur peut être référencée par un seul accessoire, on considère que cette valeur est "à référence unique". Si une valeur est ou pourrait être référencée par plusieurs accessoires, elle est dite "multi-référentielle". Remarquez qu'il est possible qu'une valeur donnée soit "à référence unique" pour un schéma et "multi-référentielle" pour un autre.
  11. D'un point de vue syntaxique, un élément peut être "indépendant" ou "incorporé". Est indépendant tout élément qui apparaît au niveau supérieur d'une sérialisation. Tous les autres éléments sont dits incorporés.

S'il est possible d'utiliser l'attribut xsi:type de sorte qu'un graphique de valeurs soit auto-descripteur à la fois de sa structure et des types de ses valeurs, les règles de sérialisation permettent que les types des valeurs PUISSENT être décrites par la seule référence à un schéma. Ces schémas PEUVENT être dans la notation décrite par "XML Schema Part 1: Structures" [10] et "XML Schema Part 2: Datatypes" [11] ou PEUVENT être dans toute autre notation. Remarquez également que, si les règles de sérialisation s'appliquent à d'autres types composés que les tableaux et les structures, de nombreux schémas ne contiennent que des types structure et tableau.

Les règles de sérialisation sont les suivantes :

  1. Toutes les valeurs sont représentées comme des contenus d'élément. Une valeur multi-référentielle DOIT ABSOLUMENT être représentée comme le contenu d'un élément indépendant. En revanche, une valeur à référence unique NE le DEVRA PAS (mais PEUT l'être).
  2. Pour chaque élément contenant une valeur, le type de la valeur DOIT ABSOLUMENT être représenté par au moins l'une des conditions suivantes : (a) l'instance d'élément contenant contient un attribut xsi:type, (b) l'instance d'élément contenant est elle-même contenue dans un élément contenant un attribut SOAP-ENC:arrayType (éventuellement défini par défaut) ou (c) le nom de l'élément définit la relation au type, ce type étant lui-même déterminable à partir d'un schéma.
  3. Une valeur simple est représentée comme une donnée caractère, c'est-à-dire sans sous-élément. Toute valeur simple doit avoir un type qui soit répertorié dans la partie 2 des spécifications des schémas XML [11] ou bien un type dont le type de source apparaît ici (voir également la section 5.2).
  4. Une valeur composée est codée sous forme d'une séquence d'éléments, chaque accessoire étant représenté par un élément incorporé dont le nom correspond au nom de l'accessoire. Les accessoires dont les noms sont locaux vis-à-vis des types qui les renferment ont des noms d'éléments non qualifiés ; tous les autres ont des noms qualifiés (voir également la section 5.4).
  5. Une valeur simple ou composée multi-référentielle est codée sous forme d'un élément indépendant contenant un attribut local non qualifié appelé "id" et de type "ID", selon la spécification XML [7]. Chaque accessoire vers cette valeur est un élément vide comportant un attribut local non qualifié appelé "href" et de type "uri-reference", selon la spécification de schéma XML [11], avec une valeur d'attribut "href" d'un identificateur de fragment d'URI référençant l'élément indépendant correspondant.
  6. Les chaînes et les tableaux d'octets sont représentés comme des types simples multi-référentiels, mais des règles spéciales permettent de les représenter de façon efficace pour les cas les plus courants (voir également les sections 5.2.1 et 5.2.3). Les accessoires vers une valeur de type chaîne ou tableau d'octets PEUVENT avoir un attribut appelé "id" et de type "ID", selon la spécification XML [7]. Si c'est le cas, tous les autres accessoires vers la même valeur sont codés sous forme d'éléments vides ayant un attribut local non qualifié appelé "href" et de type "uri-reference", selon la spécifications de schéma XML [11], avec une valeur d'attribut "href" d'un identificateur de fragment d'URI référençant l'élément indépendant contenant la valeur.
  7. Il est permis de coder plusieurs références à une valeur comme s'il s'agissait de références à plusieurs valeurs différentes, mais uniquement lorsque le contexte indique que la signification de l'instance XML est inchangée.
  8. Les tableaux sont des valeurs composées (voir également la section 5.4.2). Les tableaux SOAP sont définis comme étant de type "SOAP-ENC:Array" ou dérivé.

    Les tableaux SOAP ont une ou plusieurs dimensions (rang) dont les membres sont différenciés par leur position ordinale. Une valeur de tableau est représentée sous forme d'une série d'éléments reflétant le tableau, dont les membres apparaissent en ordre ascendant. Pour les tableaux multidimensionnels, c'est la dimension située sur le côté droit qui varie le plus rapidement. Chaque élément membre est nommé comme un élément indépendant (voir la règle 2).

    Les tableaux SOAP peuvent être des valeurs à référence unique ou multi-référentielles et peuvent par conséquent être représentés comme le contenu d'un élément incorporé ou d'un élément indépendant.

    Les tableaux SOAP DOIVENT ABSOLUMENT contenir un attribut "SOAP-ENC:arrayType" dont la valeur spécifie le type des éléments contenus ainsi que la ou les dimension(s) du tableau. La valeur de l'attribut "SOAP-ENC:arrayType" est définie comme suit :
    arrayTypeValue = atype asize
     atype = QName *( rank )
     rank = "[" *( "," ) "]"
     asize = "[" #length "]"
     length = 1*DIGIT
    
    La structure "atype" est le nom de type des éléments contenus exprimés sous forme de QName comme il apparaîtrait dans l'attribut "type" d'une déclaration d'élément de schéma XML. Elle agit comme une contrainte de type (c'est-à-dire que toutes les valeurs des éléments contenus sont garantis conformes au type indiqué, à savoir : le type cité dans SOAP-ENC:arrayType doit être le même type ou un type supérieur de chaque membre du tableau). Dans le cas de tableaux de tableaux ou "tableaux dentelés", le composant type est codé comme étant le nom de type "essentiel" suivi d'une structure de rangs pour chaque niveau de tableau imbriqué en commençant par 1. Le codage des tableaux multidimensionnels utilise une virgule pour chaque dimension en commençant par 1.

    La structure "asize" contient une liste de zéros, de un ou plusieurs entiers séparés par des virgules et indiquant la longueur de chaque dimension du tableau. Une valeur de zéro indique qu'aucune quantité n'est garantie mais que la taille peut être déterminée grâce à l'examen des membres en cours.

    Par exemple, un tableau comprenant 5 membres de type tableau d'entiers a une valeur arrayTypeValue de "int[][5]", dont la valeur atype est "int[]" et la valeur asize est "[5]". De même, un tableau comportant 3 membres de type tableaux d'entiers bidimensionnels a une valeur arrayTypeValue de "int[,][3]", dont la valeur atype est "int[,]" et la valeur asize est "[3]".

    Un membre de tableau SOAP PEUT contenir un attribut "SOAP-ENC:offset" indiquant la position de référence de cet article dans le tableau qui le contient. Cela peut être utilisé pour indiquer la position de référence d'un tableau partiellement représenté (voir la section 5.4.2.1). De même, le membre d'un tableau PEUT contenir un attribut "SOAP-ENC:position" indiquant la position de cet article dans le tableau qui le contient. Cela peut être utilisé pour décrire les membres des tableaux fragmentés (voir la section 5.4.2.2). La valeur des attributs "SOAP-ENC:offset" et "SOAP-ENC:position" est définie comme suit :

    arrayPoint = "[" #length "]"
    
    les références et positions commencent par 0.
  9. Une valeur NULL ou une valeur par défaut PEUT être représentée par l'omission de l'élément accessoire. Une valeur NULL PEUT également être indiquée par un élément accessoire contenant l'attribut xsi:null avec une valeur de "1" ou éventuellement d'autres attributs et valeurs dépendants de l'application.

Remarquez que la règle 2 permet aux éléments indépendants et aux éléments représentant les membres de tableaux d'avoir des noms différents du type de la valeur contenue.

5.2 Types simples

Pour les types simples, SOAP adopte tous les types que l'on trouve à la section "Built-in datatypes" de la spécification "XML Schema Part 2: Datatypes" [11], tant pour les espaces de valeurs que pour les espaces lexicaux :

Type Exemple
int 58502
float 314159265358979E+1
negativeInteger -32768
string Louis "Satchmo" Armstrong

Les types de données déclarées dans la spécification de schéma XML peuvent être utilisés directement dans les schémas d'éléments. Les types qui en sont dérivés peuvent également être utilisés. Voici un exemple d'un fragment de schéma et des données d'instance correspondantes avec des éléments de ce type :

<element name="age" type="int"/>
<element name="height" type="float"/>
<element name="displacement" type="negativeInteger"/>
<element name="color">
 <simpleType base="xsd:string">
 <enumeration value="Vert"/>
 <enumeration value="Bleu"/>
 </simpleType>
</element>

<age>45</age>
<height>176</height>
<displacement>-450</displacement>
<color>Bleu</color>

Toutes les valeurs simples DOIVENT ABSOLUMENT être codées en tant que contenu des éléments dont le type est défini dans la spécification "XML Schema Part 2: Datatypes" [11] ou est basé sur un type y figurant, au moyen des mécanismes fournis dans la spécification de schéma XML.

Si une valeur simple est codée comme élément indépendant ou comme membre d'un tableau hétérogène, il est utile de disposer d'une déclaration d'élément correspondant au type de données. Dans la mesure où la spécification "XML Schema Part 2: Datatypes" [11] inclut des définitions de type mais ne fournit pas les déclarations d'élément correspondantes, le schéma et l'espace de noms SOAP-ENC déclarent un élément pour chaque type de données simple. Ces éléments PEUVENT être utilisés.

<SOAP-ENC:int id="int1">45</SOAP-ENC:int>

5.2.1 Chaînes

Le type de données "string" est défini dans la spécification "XML Schema Part 2: Datatypes" [11]. Remarquez que ce type est différent du type appelé "string" dans la plupart des bases de données ou des langages de programmation et peut notamment interdire certains caractères que ces langages autorisent (ces valeurs doivent être représentées par un type de données autre que xsd:string).

Une chaîne PEUT être codée sous forme de valeur à référence unique ou multi-référentielle.

L'élément contenant la valeur de chaîne PEUT avoir un attribut "id". Les éléments accessoires supplémentaires PEUVENT alors avoir des attributs "href" correspondants.

Par exemple, deux accessoires vers la même chaîne pourraient apparaître de la façon suivante :

<greeting id="String-0">Bonjour</greeting>
<salutation class="n" href="#String-0"/>

Toutefois, si le fait que les deux accessoires référencent la même instance de la chaîne (ou d'un sous-type de la chaîne) est immatériel, les deux accessoires peuvent être codés comme deux valeurs à référence unique :

<greeting>Bonjour</greeting>
<salutation>Bonjour</salutation>

Les fragments de schéma de ces exemples pourraient ressembler à l'exemple suivant :

<element name="greeting" type="SOAP-ENC:string"/>
<element name="salutation" type="SOAP-ENC:string"/>

(Dans cet exemple, le type SOAP-ENC:string est utilisé comme type de l'élément. En effet, c'est un moyen pratique de déclarer un élément dont le type de données est "xsd:string" qui permet en outre d'insérer des attributs "id" et "href". Veuillez vous reporter au schéma de codage SOAP pour la définition exacte. Les schémas PEUVENT utiliser les déclarations tirées du schéma de codage SOAP mais cela n'est pas obligatoire).

5.2.2 Énumérations

La spécification "XML Schema Part 2: Datatypes" [11] définit un mécanisme appelé "énumération". Le modèle de données SOAP adopte directement ce mécanisme. Toutefois, comme les langages de programmation et autres définissent souvent l'énumération de façon différente, nous expliquons ici le concept dans les détails et décrivons comment une valeur membre d'une liste énumérée de valeurs possibles doit être codée. Plus spécifiquement, elle est codée comme le nom de la valeur.

L'"énumération" en tant que concept indique un ensemble de noms différents. Une énumération spécifique est une liste spécifique de valeurs distinctes appropriées au type de base. Par exemple, l'ensemble des noms de couleurs ("vert", "bleu", "marron") pourrait être défini comme une énumération basée sur le type intégré de chaîne. Les valeurs ("1", "3", "5") sont une énumération possible basée sur un entier, etc. "XML Schema Part 2: Datatypes" [11] prend en charge les énumérations de tous les types simples à l'exception du booléen. Le langage de la spécification "XML Schema Part 1: Structures" [10] peut être utilisé pour définir les types d'énumération. Si un schéma est généré à partie d'une autre notation dans laquelle aucun type de base spécifique n'est applicable, utilisez "string". Dans l'exemple de schéma suivant, "EyeColor" est défini comme une chaîne pouvant prendre les valeurs "Vert", "Bleu" ou "Marron" énumérées, et l'instance de données correspondante est donnée.

<element name="EyeColor" type="tns:EyeColor"/>
<simpleType name="EyeColor" base="xsd:string">
 <enumeration value="Vert"/>
 <enumeration value="Bleu"/>
 <enumeration value="Marron"/>
</simpleType>
<Person>
 <Name>Henry Ford</Name>
 <Age>32</Age>
 <EyeColor>Marron</EyeColor>
</Person>

5.2.3 Tableau d'octets

Un tableau d'octets PEUT être codé comme une valeur à référence unique ou multi-référentielle. Les règles appliquées à un tableau d'octets sont les mêmes que celles appliquées à une chaîne.

En particulier, l'élément contenant la valeur du tableau d'octets PEUT avoir un attribut "id". Les éléments accessoires supplémentaires PEUVENT alors avoir des attributs "href" correspondants.

Il est recommandé de représenter un tableau d'octets opaque par le codage "base64", défini dans les schémas XML [10] [11] et qui utilise l'algorithme de codage base64 défini dans 2045 [13]. Toutefois, les restrictions de longueur de ligne qui s'appliquent normalement aux données base64 dans MIME ne s'appliquent pas dans SOAP. Un sous-type "SOAP-ENC:base64" est fourni pour être utilisé avec SOAP.

<picture xsi:type="SOAP-ENC:base64">
 aG93IG5vDyBicm73biBjb3cNCg==
</picture>

5.3 Accessoire polymorphe

De nombreux langages autorisent l'utilisation d'accessoires qui peuvent accéder de façon polymorphe à des valeurs de plusieurs types, chaque type étant disponible à l'exécution. Une instance d'accessoire polymorphe DOIT ABSOLUMENT contenir un attribut "xsi:type" qui décrive le type de la valeur réelle.

Par exemple, un accessoitr polymorphe appelé "cost" avec une valeur de type "xsd:float" serait codé de la façon suivante :

<cost xsi:type="xsd:float">29,95</cost>

contrairement à un accessoire "cost" dont le type de valeur est invariable :

<cost>29,95</cost>

5.4 Types composéss

SOAP définit des types correspondant aux modèles structuraux suivants, que l'on trouve souvent dans les langages de programmation :

Struct
Un "struct" est une valeur composée dans laquelle le nom de l'accessoire est la seule chose qui différencie les valeurs membres et chaque accessoire a un nom différent.
Tableau
Un "tableau" est une valeur composée dans laquelle la position ordinale est la seule chose qui différencie les valeurs membres.

SOAP autorise également la sérialisation de données qui ne sont ni de type Struct ni de type Tableau, par exemple des données que l'on trouve dans un modèle de données Directed-Labeled-Graph, dans lequel un seul nœud possède de nombreux accessoires distincts, dont certains ont plusieurs occurrences. La sérialisation SOAP n'oblige pas le modèle de données sous-jacent à faire une distinction ordonnée entre les accessoires, mais si un tel ordre existe, les accessoires DOIVENT ABSOLUMENT être codés dans cette séquence.

5.4.1 Valeurs composées, structs et références à ces valeurs

Les membres d'une valeur composée sont codés sous forme d'éléments accessoires. Lorsque les accessoires sont différenciés par leur nom (comme dans un struct, par exemple), le nom de l'accessoire est utilisé comme nom d'élément. Les accessoires dont les noms sont locaux vis-à-vis des types qui les renferment ont des noms d'éléments non qualifiés ; tous les autres ont des noms qualifiés.

Les lignes suivantes donnent un exemple d'un struct de type "Book" :

<e:Book>
 <author>Henry Ford</author>
 <preface>Texte préliminaire</preface>
 <intro>Il s'agit d'un livre.</intro>
</e:Book>

Ceci est un fragment de schéma décrivant la structure ci-dessus :

<element name="Book">
<complexType>
 <element name="author" type="xsd:string"/>
 <element name="preface" type="xsd:string"/>
 <element name="intro" type="xsd:string"/>
</complexType>
</e:Book>

Vous trouverez ci-dessous un exemple de type comprenant à la fois des membres simples et des membres complexes. Il montre deux niveaux de référencement. Remarquez que l'attribut "href" de l'élément accessoire "Author" est une référence à la valeur ayant un attribut "id" correspondant. Une construction similaire apparaît pour "Address".

<e:Book>
 <title>My Life and Work</title>
 <author class="n" href="#Person-1"/>
</e:Book>
<e:Person id="Person-1">
 <name>Henry Ford</name>
 <address class="n" href="#Address-2"/>
</e:Person>
<e:Address id="Address-2">
 <email>mailto:henryford@hotmail.com</email>
 <web>http://www.henryford.com</web>
</e:Address>

La forme ci-dessus est appropriée lorsque les valeurs "Person" et "Address" sont multi-référentielles. Si elles sont à référence unique, elles DEVRONT être incorporées de la façon suivante :

<e:Book>
 <title>My Life and Work</title>
 <author>
 <name>Henry Ford</name>
 <address>
 <email>mailto:henryford@hotmail.com</email>
 <web>http://www.henryford.com</web>
 </address>
 </author>
</e:Book>

S'il existe une restriction interdisant à deux personnes d'avoir la même adresse dans une même instance et que cette adresse peut être une adresse de rue ou une adresse électronique, un livre écrit par deux auteurs sera codé de la façon suivante :

<e:Book>
 <title>My Life and Work</title>
 <firstauthor class="n" href="#Person-1"/>
 <secondauthor class="n" href="#Person-2"/>
</e:Book>
<e:Person id="Person-1">
 <name>Henry Ford</name>
 <address xsi:type="m:Electronic-address">
 <email>mailto:henryford@hotmail.com</email>
 <web>http://www.henryford.com</web>
 </address>
</e:Person>
<e:Person id="Person-2">
 <name>Samuel Crowther</name>
 <address xsi:type="n:Street-address">
 <street>Martin Luther King Rd</street>
 <city>Raleigh</city>
 <state>Caroline du Nord</state>
 </address>
</e:Person>

Les sérialisations peuvent contenir des références à des valeurs situées dans des ressources différentes :

<e:Book>
 <title>Paradise Lost</title>
 <firstauthor class="n" href="http://www.dartmouth.edu/~milton/"/>
</e:Book>

Ceci est un fragment de schéma décrivant les structures ci-dessus :

<element name="Book" type="tns:Book"/>
<complexType name="Book">
 <!-- Seul le groupe suivant ou l'attribut href doit
 apparaître, mais pas les deux. -->
 <sequence minOccurs="0" maxOccurs="1">
 <element name="title" type="xsd:string"/>
 <element name="firstauthor" type="tns:Person"/>
 <element name="secondauthor" type="tns:Person"/>
 </sequence>
 <attribute name="href" type="uriReference"/>
 <attribute name="id" type="ID"/>
 <anyAttribute namespace="##other"/>
</complexType>

<element name="Person" base="tns:Person"/>
<complexType name="Person">
 <!-- Either the following group must occur or else the
 href attribute must appear, but not both. -->
 <sequence minOccurs="0" maxOccurs="1">
 <element name="name" type="xsd:string"/>
 <element name="address" type="tns:Address"/>
 </sequence>
 <attribute name="href" type="uriReference"/>
 <attribute name="id" type="ID"/>
 <anyAttribute namespace="##other"/>
</complexType>

<element name="Address" base="tns:Address"/>
<complexType name="Address">
 <!-- Either the following group must occur or else the
 href attribute must appear, but not both. -->
 <sequence minOccurs="0" maxOccurs="1">
 <element name="street" type="xsd:string"/>
 <element name="city" type="xsd:string"/>
 <element name="state" type="xsd:string"/>
 </sequence>
 <attribute name="href" type="uriReference"/>
 <attribute name="id" type="ID"/>
 <anyAttribute namespace="##other"/>
</complexType>

5.4.2 Tableaux

Les tableaux SOAP sont définis comme étant de type "SOAP-ENC:Array" ou dérivé (voir également la règle 8). Les tableaux sont représentés comme des valeurs d'élément, avec aucune contrainte spécifique sur le nom de l'élément contenant (à l'instar des valeurs, qui n'imposent en général aucune contrainte sur le nom de l'élément qui les contient).

Les tableaux contiennent des éléments, qui peuvent être de tout type, y compris des tableaux imbriqués. Il est possible de créer de nouveaux types à partir des restrictions de SOAP-ENC:Array pour représenter, par exemple, des tableaux réservés aux entiers ou à des énumérations définies par l'utilisateur.

La représentation de la valeur d'un tableau est une séquence ordonnée d'éléments constituant les articles du tableau. Au sein d'une valeur de tableau, les noms d'éléments ne sont pas pertinents pour différencier les accessoires. Les éléments peuvent prendre n'importe quel nom. En pratique, les éléments sont souvent nommés de façon à ce que leur déclaration dans un schéma suggère ou détermine leur type. Tout comme pour les types composés en général, si la valeur d'un élément de tableau est une valeur à référence unique, l'élément contient sa valeur. Dans le cas contraire, l'élément référence sa valeur via un attribut "href".

L'exemple suivant est un fragment de schéma et un tableau contenant dont les membres sont des entiers.

<element name="myFavoriteNumbers"
 type="SOAP-ENC:Array"/>

<myFavoriteNumbers
 SOAP-ENC:arrayType="xsd:int[2]">
 <number>3</number> 
 <number>4</number> 
</myFavoriteNumbers>

Dans cet exemple, le tableau "myFavoriteNumbers" contient plusieurs membres, chacun étant une valeur de type SOAP-ENC:int. Cela peut être déterminé en examinant l'attribut SOAP-ENC:arrayType. Remarquez que le type SOAP-ENC:Array autorise des éléments non qualifiés sans restriction. Ils ne véhiculent pas d'informations de type, donc au moment de les utiliser, il faut leur donner un attribut xsi:type ou donner à l'élément contenant un attribut SOAP-ENC:arrayType. Naturellement, les types dérivés de SOAP-ENC:Array peuvent déclarer des éléments locaux comportant des informations de type.

Comme nous l'avons noté précédemment, le schéma SOAP-ENC contient des déclarations d'éléments avec des noms correspondant à chaque type simple de la spécification "XML Schema Part 2: Datatypes" [11]. Il contient également une déclaration pour "Tableau". Si nous les utilisons, nous pouvons écrire :

<SOAP-ENC:Array SOAP-ENC:arrayType="xsd:int[2]">
 <SOAP-ENC:int>3</SOAP-ENC:int>
 <SOAP-ENC:int>4</SOAP-ENC:int>
</SOAP-ENC:Array>

Les tableaux peuvent contenir des instances de n'importe quel sous-type de l'arrayType spécifié. C'est-à-dire que les membres peuvent être n'importe quel type à condition que ce type soit substituable au type spécifié dans l'attribut arrayType, conformément aux règles de substitution exprimées dans le schéma. Donc, par exemple, un tableau d'entiers peut contenir tout type dérivé d'un entier (par exemple, "int" ou toute dérivée d'entier définie par l'utilisateur). De même, un tableau "address" peut contenir un type restreint ou étendu tel que "internationalAddress". Parce que le type SOAP-ENC:Array fourni admet des membres de tous types, des mélanges arbitraires de types peuvent être utilisés, sauf limite spécifique imposée par un attribut arrayType.

Les types d'éléments membres peuvent être spécifiés grâce à l'utilisation de l'attribut xsi:type dans l'instance ou à la déclaration dans le schéma des éléments membres, comme illustré dans les tableaux ci-dessous.

<SOAP-ENC:Array SOAP-ENC:arrayType="SOAP-ENC:ur-type[4]">
 <thing xsi:type="xsd:int">12345</thing>
 <thing xsi:type="xsd:decimal">6,789</thing>
 <thing xsi:type="xsd:string">
 Of Mans First Disobedience, and the Fruit
 Of that Forbidden Tree, whose mortal tast
 Brought Death into the World, and all our woe,
 </thing>
 <thing xsi:type="xsd:uriReference">
 http://www.dartmouth.edu/~milton/reading_room/
 </thing>
</SOAP-ENC:Array>
<SOAP-ENC:Array SOAP-ENC:arrayType="SOAP-ENC:ur-type[4]">
 <SOAP-ENC:int>12345</SOAP-ENC:int>
 <SOAP-ENC:decimal>6,789</SOAP-ENC:decimal>
 <xsd:string>
 Of Mans First Disobedience, and the Fruit
 Of that Forbidden Tree, whose mortal tast
 Brought Death into the World, and all our woe,
 </xsd:string>
 <SOAP-ENC:uriReference>
 http://www.dartmouth.edu/~milton/reading_room/
 </SOAP-ENC:uriReference > 
</SOAP-ENC:Array>

Les valeurs de tableaux peuvent être des structs ou d'autres valeurs composées. L'exemple ci-dessous montre un tableau de structs "xyz:Order" :

<SOAP-ENC:Array SOAP-ENC:arrayType="xyz:Order[2]">
 <Order>
 <Product>Pomme</Product>
 <Price>1,56</Price>
 </Order>
 <Order>
 <Product>Pêche</Product>
 <Price>1,48</Price>
 </Order>
</SOAP-ENC:Array>

Les tableaux peuvent avoir d'autres tableaux comme valeurs membres. L'exemple suivant montre un tableau composé de deux tableaux de chaînes.

<SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[][2]">
 <item class="n" href="#array-1"/>
 <item class="n" href="#array-2"/>
</SOAP-ENC:Array>
<SOAP-ENC:Array id="array-1" SOAP-ENC:arrayType="xsd:string[2]">
 <item>r1c1</item>
 <item>r1c2</item>
 <item>r1c3</item>
</SOAP-ENC:Array>
<SOAP-ENC:Array id="array-2" SOAP-ENC:arrayType="xsd:string[2]">
 <item>r2c1</item>
 <item>r2c2</item>
</SOAP-ENC:Array>

L'élément contenant une valeur de tableau n'a pas besoin d'être nommé "SOAP-ENC:Array". Il peut avoir n'importe quel nom, à condition que le type de l'élément soit SOAP-ENC:Array ou soit dérivé de SOAP-ENC:Array par restriction. L'exemple suivant montre un fragment de schéma et un tableau d'instances conforme.

<simpleType name="phoneNumber" base="string"/>

<element name="ArrayOfPhoneNumbers">
 <complexType base="SOAP-ENC:Array">
 <element name="phoneNumber" type="tns:phoneNumber" maxOccurs="unbounded"/>
 </complexType>
 <anyAttribute/>
</element>
<xyz:ArrayOfPhoneNumbers SOAP-ENC:arrayType="xyz:phoneNumber[2]">
 <phoneNumber>01 21 85 94 66</phoneNumber>
 <phoneNumber>02 93 17 23 94</phoneNumber>
</xyz:ArrayOfPhoneNumbers>

Les tableaux peuvent être multidimensionnels. Dans ce cas, la partie asize de l'attribut arrayType affichera plus d'une taille :

<SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[2,3]">
 <item>r1c1</item> 
 <item>r1c2</item> 
 <item>r1c3</item> 
 <item>r2c1</item> 
 <item>r2c2</item> 
 <item>r2c3</item> 
</SOAP-ENC:Array>

Les exemples ci-dessus montrent des tableaux codés sous forme d'éléments indépendants, mais les valeurs de tableaux PEUVENT également être incorporées et DEVRONT l'être lorsqu'il s'agira de valeurs à référence unique.

L'exemple suivant montre un fragment de schéma et un tableau de numéros de téléphone incorporé dans un struct de type "Person" auquel on accède via l'accessoire "phone-numbers" :

<simpleType name="phoneNumber" base="string"/>

<element name="ArrayOfPhoneNumbers">
 <complexType base="SOAP-ENC:Array">
 <element name="phoneNumber" type="tns:phoneNumber" maxOccurs="unbounded"/>
 </complexType>
 <anyAttribute/>
</element>

<element name="Person">
 <complexType>
 <element name="name" type="string"/>
 <element name="phoneNumbers" type="tns:ArrayOfPhoneNumbers"/>
 </complexType>
</element>
<xyz:Person>
 <name>John Hancock</name>
 <phoneNumbers SOAP-ENC:arrayType="xyz:phoneNumber[2]">
 <phoneNumber>01 21 85 94 66</phoneNumber>
 <phoneNumber>02 93 17 23 94</phoneNumber>
 </phoneNumbers>
</xyz:Person>

Voici un autre exemple de valeur de tableau à référence unique codée comme élément incorporé dont le nom de l'élément contenant est le nom de l'accessoire :

<xyz:PurchaseOrder>
 <CustomerName>Henry Ford</CustomerName>
 <ShipTo>
 <Street>5th Ave</Street>
 <City>New York</City>
 <State>NY</State>
 <Zip>10010</Zip>
 </ShipTo>
 <PurchaseLineItems SOAP-ENC:arrayType="Order[2]">
 <Order>
 <Product>Pomme</Product>
 <Price>1,56</Price>
 </Order>
 <Order>
 <Product>Pêche</Product>
 <Price>1,48</Price>
 </Order>
 </PurchaseLineItems>
</xyz:PurchaseOrder>
5.4.2.1 Tableaux partiellement transmis

SOAP prend en charge la transmission partielle des tableaux, appelés tableaux "variables" dans certains contextes [12]. Un tableau partiellement transmis indique dans un attribut "SOAP-ENC:offset" une référence à l'origine zéro du premier élément transmis. Si cet attribut est omis, la référence prise en compte est zéro.

L'exemple suivant montre un tableau de taille cinq qui transmet uniquement les troisième et quatrième éléments à partir de zéro :

<SOAP-ENC:Array ;SOAP-ENC:arrayType="xsd:string[5]" ;SOAP-ENC:offset="[2]"> 
 <item>Le troisième élément</item> 
 <item>Le quatrième élément</item>
</SOAP-ENC:Array>
5.4.2.2 Tableaux fragmentés

SOAP prend en charge les tableaux fragmentés. Chaque élément représentant une valeur membre contient un attribut "SOAP-ENC:position" qui indique sa position dans le tableau. L'exemple suivant montre un tableau fragmenté de tableaux de chaînes à deux dimensions. La taille est de 4 mais seule la position 2 est utilisée :

<SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[,][4]">
 <SOAP-ENC:Array class="n" href="#array-1" SOAP-ENC:position="[2]"/>
</SOAP-ENC:Array>
<SOAP-ENC:Array id="array-1" SOAP-ENC:arrayType="xsd:string[10,10]">
 <item SOAP-ENC:position="[2,2]">Troisième ligne, troisième colonne</item>
 <item SOAP-ENC:position="[7,2]">Huitième ligne, troisième colonne</item>
</SOAP-ENC:Array>

Si la seule référence au tableau-1 est faite dans le tableau contenant, cet exemple aurait pu également être codé de la façon suivante :

<SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[,][4]">
 <SOAP-ENC:Array SOAP-ENC:position="[2]" SOAP-ENC:arrayType="xsd:string[10,10]>
 <item SOAP-ENC:position="[2,2]">Troisième ligne, troisième colonne</item>
 <item SOAP-ENC:position="[7,2]">Huitième ligne, troisième colonne</item>
 </SOAP-ENC:Array>
</SOAP-ENC:Array>
5.4.3 Types composés génériques

Les règles de codage que nous venons de mentionner ne sont pas limitées aux cas où les noms d'accessoires sont connus à l'avance. Si les noms des accessoires ne peuvent être connus qu'en examinant au cas par cas les valeurs à coder, les mêmes règles s'appliquent, c'est-à-dire que l'accessoire est codé sous forme d'élément dont le nom correspond au nom de l'accessoire, et l'accessoire ne contient pas sa valeur et n'y fait pas référence. Les accessoires contenant des valeurs dont les types ne peuvent pas être connus par avance DOIVENT ABSOLUMENT contenir un attribut xsi:type approprié qui donne le type de la valeur.

De même, les règles mentionnées sont suffisantes pour autoriser la sérialisation de types composés comprenant un mélange d'accessoires différenciés par nom et d'accessoires différenciés à la fois par leur nom et par leur position ordinale (c'est-à-dire comprenant plusieurs occurrences d'un même accessoire). Cela n'implique pas qu'un schéma doive obligatoirement contenir de tels types. Disons plutôt que si un schéma de modèle de type comporte de tels types, un schéma et une instance syntaxiques XML correspondants pourront être générés.

<xyz:PurchaseOrder>
 <CustomerName>Henry Ford</CustomerName>
 <ShipTo>
 <Street>5th Ave</Street>
 <City>New York</City>
 <State>NY</State>
 <Zip>10010</Zip>
 </ShipTo>
 <PurchaseLineItems>
 <Order>
 <Product>Pomme</Product>
 <Price>1,56</Price>
 </Order>
 <Order>
 <Product>Pêche</Product>
 <Price>1,48</Price>
 </Order>
 </PurchaseLineItems>
</xyz:PurchaseOrder>

De même, il est possible de sérialiser une valeur composée qui ressemble d'un point de vue structurel à un tableau mais qui n'est pas de type (ou de sous-type) SOAP-ENC:Array. Par exemple :

<PurchaseLineItems>
 <Order>
 <Product>Pomme</Product>
 <Price>1,56</Price>
 </Order>
 <Order>
 <Product>Pêche</Product>
 <Price>1,48</Price>
 </Order>
</PurchaseLineItems>

5.5 Valeurs par défaut

L'omission d'un élément accessoire implique une valeur par défaut ou signifie que la valeur est inconnue. Les particularités dépendent de l'accessoire, de la méthode et de son contexte. Par exemple, l'omission d'un accessoire implique en général une valeur Null pour les accessoires polymorphes (ou plus exactement dépendant d'un accessoire Null). De même, l'omission d'un accessoire booléen implique en général une valeur False ou signifie que la valeur n'est pas connue et l'omission d'un accessoire numérique implique que la valeur est zéro ou signifie que la valeur n'est pas connue.

5.6 Attribut racine de SOAP

L'attribut racine de SOAP peut être utilisé pour étiqueter les racines de sérialisation qui ne sont pas les véritables racines d'un objet graphique, de façon à ce que cet objet graphique puisse être désérialisé. L'attribut peut avoir une ou deux valeurs : "1" ou "0". Les véritables racines d'un objet graphique ont une valeur d'attribut implicite de "1". Les racines de sérialisation qui ne sont pas de véritables racines peuvent être étiquetées comme racines de sérialisation avec une valeur d'attribut de "1". Un élément peut être explicitement étiqueté comme n'étant pas une racine de sérialisation via une valeur de "0".

L'attribut racine de SOAP PEUT apparaître sur tout sous-élément au sein des éléments Header et Body de SOAP. L'attribut n'a pas de valeur par défaut.

6. Utilisation de SOAP dans HTTP

Cette section décrit comment utiliser SOAP dans HTTP, avec ou sans la structure d'extension HTTP. Le fait de lier SOAP à HTTP nous permet d'utiliser la forme et la flexibilité décentralisée de SOAP tout en bénéficiant des fonctionnalités utiles de HTTP. Associer SOAP à HTTP ne signifie pas que SOAP va redéfinir la sémantique de HTTP mais plutôt que la sémantique de SOAP mappe naturellement la sémantique de HTTP.

SOAP suit naturellement le modèle de message requête/réponse HTTP en fournissant des paramètres de requête SOAP dans les requêtes HTTP et des paramètres de réponse SOAP dans les réponses HTTP. Remarquez néanmoins que les intermédiaires SOAP sont DIFFÉRENTS des intermédiaires HTTP. En effet, un intermédiaire HTTP géré avec le champ d'en-tête HTTP connection ne peut pas explorer ni traiter le corps d'une entité SOAP transmis dans une requête HTTP.

Les applications HTTP DOIVENT ABSOLUMENT utiliser le type de support "text/xml" conformément à RFC 2376 [3] lorsqu'elles insèrent des corps d'entités SOAP dans des messages HTTP.

6.1 Requête SOAP HTTP

Bien que SOAP puisse être associé à une grande variété de méthodes de requête HTTP, cette liaison définit uniquement SOAP dans les requêtes HTTP POST (voir section 7 sur la façon d'utiliser SOAP pour RPC et section 6.3 sur la façon d'utiliser la structure d'extension HTTP).

6.1.1 Le champ d'en-tête HTTP SOAPAction

Le champ d'en-tête de requête HTTP SOAPAction peut être utilisé pour indiquer l'intention de la requête SOAP HTTP. La valeur est un URI identifiant l'intention. SOAP n'impose de restriction ni sur le format, ni sur la spécificité de l'URI, ni sur ce qu'il est possible de résoudre. Un client HTTP DOIT ABSOLUMENT utiliser ce champ d'en-tête lorsqu'il émet une requête SOAP HTTP.

soapaction = "SOAPAction" ":" [ <"> URI-reference <"> ]
URI-reference = <as defined in RFC 2396 [4]>

Le champ d'en-tête SOAPAction et son contenu permettent aux serveurs comme les pare-feu de filtrer de façon appropriée les messages de requête SOAP dans HTTP. La valeur de champ d'en-tête d'une chaîne vide ("") indique que l'intention du message SOAP est fournie par l'URI de requête HTTP. L'absence de valeur signifie qu'il n'y a aucune indication de l'intention de ce message.

Exemples :

SOAPAction: "http://electrocommerce.org/abc#MyMessage"
SOAPAction: "myapp.sdl"
SOAPAction: ""
SOAPAction:

6.2 Réponse SOAP HTTP

SOAP HTTP suit la sémantique des codes d'état HTTP pour les informations d'état de la communication dans HTTP. Par exemple, le code d'état 2xx indique que la requête du client comprenant le composant SOAP a été reçue, comprise, acceptée, etc., avec succès.

En cas d'erreur SOAP lors du traitement de la requête, le serveur SOAP HTTP DOIT ABSOLUMENT émettre une réponse HTTP 500 "Erreur interne du serveur" et insérer un message SOAP dans la réponse comprenant l'élément SOAP défectueux (voir section 4.4) indiquant l'erreur de traitement SOAP.

6.3 La structure d'extension HTTP

Un message SOAP PEUT être associé à la structure d'extension HTTP [6] pour pouvoir détecter la présence et définir l'intention d'une requête SOAP HTTP.

Le choix d'utiliser HTTP avec ou sans la structure d'extension dépend de la stratégie adoptée et de la capacité de communication des parties. Les clients peuvent rendre obligatoire l'utilisation de la structure d'extension HTTP en utilisant une déclaration d'extension impérative et le préfixe de nom de méthode HTTP "M-". Les serveurs peuvent rendre obligatoire l'utilisation de la structure d'extension HTTP en utilisant le code d'état HTTP 510 "Non étendu". Ainsi, avec un aller-retour de plus, chaque partie peut détecter la stratégie adoptée par l'autre et agir en conséquence.

L'identificateur d'extension utilisé pour identifier SOAP avec la structure d'extension est

http://schemas.xmlsoap.org/soap/envelope/

6.4 Exemples SOAP HTTP

Exemple 3. SOAP HTTP avec POST

POST /StockQuote HTTP/1.1
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn
SOAPAction: "http://electrocommerce.org/abc#MyMessage"

<SOAP-ENV:Envelope...

HTTP/1.1 200 OK
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn

<SOAP-ENV:Envelope...

Exemple 4. SOAP avec la structure d'extension HTTP

M-POST /StockQuote HTTP/1.1
Man: "http://schemas.xmlsoap.org/soap/envelope/"; ns=NNNN
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn
NNNN-SOAPAction: "http://electrocommerce.org/abc#MyMessage"

<SOAP-ENV:Envelope...

HTTP/1.1 200 OK
Ext:
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn

<SOAP-ENV:Envelope...

7. Utilisation de SOAP pour les appels de procédure à distance (RPC)

L'un des objectifs de conception de SOAP est d'encapsuler et d'échanger les appels RPC en bénéficiant de l'extensibilité et de la flexibilité de XML. Cette section définit une représentation uniforme des appels et réponses de procédure à distance.

Même si l'on sait que cette représentation sera probablement utilisée en association avec le style d'encodage défini dans la section 5, d'autres représentations sont possibles. L'attribut SOAP encodingStyle (voir section 4.3.2) peut être utilisé pour indiquer le style d'encodage de l'appel de méthode et la réponse à partir de la représentation décrite dans cette section.

L'utilisation de SOAP pour RPC est orthogonale à la liaison du protocole SOAP (voir section 6). L'utilisation de HTTP comme liaison de protocole permet de mapper les appels RPC sur les requêtes HTTP ainsi que les réponses RPC sur les réponses HTTP. Toutefois, l'utilisation de SOAP pour RPC ne se limite pas à la liaison de protocole HTTP.

Pour effectuer un appel de méthode, il faut fournir les informations suivantes :

  • L'URI de l'objet de destination
  • Un nom de méthode
  • Une signature de méthode optionnelle
  • Les paramètres de la méthode
  • Les données d'en-tête optionnelles

SOAP se sert de la liaison de protocole pour fournir un mécanisme de transfert des URI. Par exemple, pour HTTP l'URI de la requête indique la ressource concernée par l'invocation. Hormis la nécessité d'utiliser un URI valide, SOAP ne place aucune restriction quant à la forme de l'adresse (voir [4] pour plus d'informations sur les URI).

7.1 Appels de procédure à distance (RPC) et corps SOAP

Les appels de méthode RPC et les réponses à ces méthodes sont tous deux effectués dans l'élément Body de SOAP (voir section 4.3) grâce à la représentation suivante :

  • Une invocation de méthode est modelée sous forme d'un struct.
  • L'invocation de méthode est considérée comme un seul struct contenant un accessoire pour chaque paramètre [entrée] ou [entrée/sortie]. Le nom et le type du struct sont calqués sur le nom de la méthode.
  • Chaque paramètre [entrée] ou [entrée/sortie] est considéré comme un accessoire doté d'un nom correspondant au nom du paramètre et d'un type correspondant au type du paramètre. Ces indications apparaissent dans le même ordre que dans la signature de méthode.
  • Une réponse de méthode est modelée sous forme d'un struct.
  • La réponse de méthode est considérée comme un seul struct contenant un accessoire pour la valeur de retour et chaque paramètre [sortie] ou [entrée/sortie]. Le premier accessoire correspond à la valeur de retour suivie des paramètres apparaissant dans le même ordre que dans la signature de méthode.
  • Chaque accessoire de paramètre est doté d'un nom correspondant au nom du paramètre et d'un type correspondant au type du paramètre. Le nom de l'accessoire de valeur de retour n'est pas important. De même, le nom du struct n'est pas important. Néanmoins, la convention veut qu'on l'appelle d'après le nom de la méthode en ajoutant la chaîne "Response".
  • Les erreurs de méthode sont codées grâce à l'élément Fault de SOAP (voir section 4.4). Si une liaison de protocole ajoute des règles supplémentaires pour l'expression des erreurs, ces règles DOIVENT ABSOLUMENT être également respectées.

Comme signalé ci-dessus, les structs de méthode et de réponse peuvent être codés selon les règles de la section 5, mais d'autres codages peuvent également être spécifiés à l'aide de l'attribut encodingStyle (voir section 4.1.1).

Les applications PEUVENT traiter les requêtes même s'il leur manque des paramètres mais PEUVENT également renvoyer une erreur.

Étant donné qu'un résultat indique un succès, et une erreur un échec, la réponse d'une méthode ne doit pas contenir à la fois un résultat et une erreur.

7.2 Appels de procédure à distance et en-tête SOAP

D'autres informations utiles pour le codage d'une requête de méthode, mais ne faisant pas partie de la signature de méthode formelle, PEUVENT être exprimées dans le codage RPC. Dans ce cas, elles DOIVENT ABSOLUMENT être exprimées comme sous-élément de l'élément Header de SOAP.

Pour illustrer l'utilisation de l'élément d'en-tête, prenons l'exemple de la transmission de l'ID d'une transaction avec un message. Comme l'ID de la transaction ne fait pas partie de la signature et figure généralement dans un composant d'infrastructure et non dans le code de l'application, il n'existe pas de moyen direct de transmettre les informations nécessaires avec l'appel. En ajoutant une entrée aux en-têtes et en donnant à cette entrée un nom déterminé. Le gestionnaire de transaction côté réception peut extraire l'ID de transaction et l'utiliser sans affecter le code des appels de procédure à distance.

8. Questions de sécurité

Les méthodes garantissant l'intégrité et la protection de la vie privée ne sont pas décrites dans ce document. Ces questions seront abordées en détail dans une ou plusieurs version(s) future(s) de ce document.

9. Références (documents en anglais)

[1] S. Bradner, "The Internet Standards Process -- Revision 3", RFC2026, Harvard University, octobre 1996

[2] S. Bradner, "Key words for use in RFCs to Indicate Requirement Levels", RFC 2119, Harvard University, mars 1997

[3] E. Whitehead, M. Murata, "XML Media Types", RFC2376, UC Irvine, Fuji Xerox Info. Systems, juillet 1998

[4] T. Berners-Lee, R. Fielding, L. Masinter, "Uniform Resource Identifiers (URI): Generic Syntax", RFC 2396, MIT/LCS, U.C. Irvine, Xerox Corporation, août 1998.

[5] R. Fielding, J. Gettys, J. C. Mogul, H. Frystyk, T. Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1", RFC 2616, U.C. Irvine, DEC W3C/MIT, DEC, W3C/MIT, W3C/MIT, janvier 1997

[6] H. Nielsen, P. Leach, S. Lawrence, "An HTTP Extension Framework", RFC 2774, Microsoft, Microsoft, Agranat Systems

[7] W3C Recommendation "The XML Specification"

[8] W3C Recommendation "Namespaces in XML"

[9] W3C Working Draft "XML Linking Language". Travail en cours.

[10] W3C Working Draft "XML Schema Part 1: Structures". Travail en cours.

[11] W3C Working Draft "XML Schema Part 2: Datatypes". Travail en cours.

[12] Transfer Syntax NDR, in "DCE 1.1: Remote Procedure Call"

[13] N. Freed, N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies", RFC2045, Innosoft, First Virtual, novembre 1996

A. Exemples d'enveloppe SOAP

A.1 Exemple de codage des requêtes d'appel

Exemple 5. Similaire à l'exemple 1 mais avec un en-tête obligatoire

POST /StockQuote HTTP/1.1
Host: www.stockquoteserver.com
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn
SOAPAction: "Some-URI"

<SOAP-ENV:Envelope
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
 <SOAP-ENV:Header>
 <t:Transaction
 xmlns:t="some-URI"
 SOAP-ENV:mustUnderstand="1">
 5
 </t:Transaction>
 </SOAP-ENV:Header>
 <SOAP-ENV:Body>
 <m:GetLastTradePrice xmlns:m="Some-URI">
 <symbol>DEF</symbol>
 </m:GetLastTradePrice>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Exemple 6. Similaire à l'exemple 1 mais avec plusieurs paramètres de requête

POST /StockQuote HTTP/1.1
Host: www.stockquoteserver.com
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn
SOAPAction: "Some-URI"

<SOAP-ENV:Envelope
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
 <SOAP-ENV:Body>
 <m:GetLastTradePriceDetailed
 xmlns:m="Some-URI">
 <Symbol>DEF</Symbol>
 <Company>DEF Corp</Company>
 <Price>34.1</Price>
 </m:GetLastTradePriceDetailed>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

A.2 Exemple de codage d'une réponse

Exemple 7. Similaire à l'exemple 2 mais avec un en-tête obligatoire

HTTP/1.1 200 OK
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn

<SOAP-ENV:Envelope
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
 <SOAP-ENV:Header>
 <t:Transaction
 xmlns:t="some-URI"
 xsi:type="xsd:int" mustUnderstand="1">
 5
 </t:Transaction>
 </SOAP-ENV:Header>
 <SOAP-ENV:Body>
 <m:GetLastTradePriceResponse
 xmlns:m="Some-URI">
 <Price>34,5</Price>
 </m:GetLastTradePriceResponse>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Exemple 8. Similaire à l'exemple 2 mais avec un struct

HTTP/1.1 200 OK
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn

<SOAP-ENV:Envelope
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
 <SOAP-ENV:Body>
 <m:GetLastTradePriceResponse
 xmlns:m="Some-URI">
 <PriceAndVolume>
 <LastTradePrice>
 34,5
 </LastTradePrice>
 <DayVolume>
 10000
 </DayVolume>
 </PriceAndVolume>
 </m:GetLastTradePriceResponse>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Exemple 9. Similaire à l'exemple 2 mais échec du respect de l'en-tête obligatoire

HTTP/1.1 500 Internal Server Error
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn

<SOAP-ENV:Envelope
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
 <SOAP-ENV:Body>
 <SOAP-ENV:Fault>
 <faultcode>SOAP-ENV:MustUnderstand</faultcode>
 <faultstring>SOAP doit comprendre l'erreur</faultstring>
 </SOAP-ENV:Fault>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Exemple 10. Similaire à l'exemple 2 mais échec de la prise en charge de l'élément Body

HTTP/1.1 500 Internal Server Error
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn

<SOAP-ENV:Envelope
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
 <SOAP-ENV:Body>
 <SOAP-ENV:Fault>
 <faultcode>SOAP-ENV:Server</faultcode>
 <faultstring>Erreur du serveur</faultstring>
 <detail>
 <e:myfaultdetails xmlns:e="Some-URI">
 <message>
 Mon appmication n'a pas fonctionné
 </message>
 <errorcode>
 1001
 </errorcode>
 </e:myfaultdetails>
 </detail>
 </SOAP-ENV:Fault>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>


Dernière mise à jour le jeudi 3 août 2000



Afficher: