Qu’est-ce que WSDL ?
WSDL est un langage XML qui décrit complètement un service web :
- Les opérations disponibles
- Les formats des messages (entrée/sortie)
- Les protocoles de communication
- L’emplacement du service
Structure d’un fichier WSDL
Un fichier WSDL se compose de 6 sections principales, de l’abstrait au concret :
definitions (racine)
├── types (schémas des données)
├── message (définition des messages)
├── portType (interface abstraite)
├── binding (protocole concret)
└── service (point d'accès)
1. Definitions (Racine)
Élément racine qui englobe tout le document WSDL.
<definitions
name="BankingService"
targetNamespace="http://www.example.com/banking"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://www.example.com/banking"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- Contenu du WSDL -->
</definitions>Attributs importants :
name: Nom du servicetargetNamespace: Namespace du service (URI unique)- Déclarations des namespaces utilisés
2. Types (Schémas des données)
Définit les types de données complexes utilisés par le service via XML Schema.
<types>
<xsd:schema targetNamespace="http://www.example.com/banking">
<!-- Type complexe : Compte -->
<xsd:complexType name="Account">
<xsd:sequence>
<xsd:element name="accountNumber" type="xsd:string"/>
<xsd:element name="accountType" type="xsd:string"/>
<xsd:element name="balance" type="xsd:decimal"/>
</xsd:sequence>
</xsd:complexType>
<!-- Type complexe : Transfert -->
<xsd:complexType name="TransferRequest">
<xsd:sequence>
<xsd:element name="fromAccount" type="xsd:string"/>
<xsd:element name="toAccount" type="xsd:string"/>
<xsd:element name="amount" type="xsd:decimal"/>
<xsd:element name="currency" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="TransferResponse">
<xsd:sequence>
<xsd:element name="transactionId" type="xsd:string"/>
<xsd:element name="status" type="xsd:string"/>
<xsd:element name="timestamp" type="xsd:dateTime"/>
</xsd:sequence>
</xsd:complexType>
<!-- Type simple avec restriction -->
<xsd:simpleType name="AccountStatus">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="ACTIVE"/>
<xsd:enumeration value="SUSPENDED"/>
<xsd:enumeration value="CLOSED"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
</types>Types XSD courants :
xsd:string: Chaîne de caractèresxsd:int/xsd:integer: Nombres entiersxsd:decimal: Nombres décimauxxsd:boolean: Booléenxsd:dateTime: Date et heurexsd:date: Date seulement
3. Message (Définition des messages)
Définit les messages échangés (paramètres et retours).
<!-- Message pour la requête de transfert -->
<message name="TransferFundsRequest">
<part name="parameters" type="tns:TransferRequest"/>
</message>
<!-- Message pour la réponse de transfert -->
<message name="TransferFundsResponse">
<part name="parameters" type="tns:TransferResponse"/>
</message>
<!-- Message pour obtenir le solde -->
<message name="GetBalanceRequest">
<part name="accountNumber" type="xsd:string"/>
</message>
<message name="GetBalanceResponse">
<part name="balance" type="xsd:decimal"/>
</message>
<!-- Message d'erreur -->
<message name="BankingFault">
<part name="errorCode" type="xsd:string"/>
<part name="errorMessage" type="xsd:string"/>
</message>Éléments :
name: Nom unique du messagepart: Partie du message (peut en avoir plusieurs)name: Nom du paramètretype: Type de donnée (référence à types ou XSD)element: Alternative à type, référence un élément XML
4. PortType (Interface abstraite)
Définit l’interface du service : les opérations disponibles et leurs messages.
<portType name="BankingPortType">
<!-- Opération Request-Response -->
<operation name="TransferFunds">
<documentation>Effectue un transfert entre deux comptes</documentation>
<input message="tns:TransferFundsRequest"/>
<output message="tns:TransferFundsResponse"/>
<fault name="InvalidAccountFault" message="tns:BankingFault"/>
</operation>
<!-- Opération Request-Response simple -->
<operation name="GetBalance">
<documentation>Obtient le solde d'un compte</documentation>
<input message="tns:GetBalanceRequest"/>
<output message="tns:GetBalanceResponse"/>
</operation>
<!-- Opération One-Way (pas de réponse) -->
<operation name="NotifyTransaction">
<input message="tns:TransactionNotification"/>
</operation>
</portType>Patterns d’opération :
- Request-Response : input + output (le plus courant)
- One-way : input seulement (notification)
- Notification : output seulement (push du serveur)
- Solicit-Response : output + input (rare)
5. Binding (Protocole concret)
Définit comment les opérations sont transmises via un protocole (généralement SOAP).
<binding name="BankingSOAPBinding" type="tns:BankingPortType">
<!-- Configuration SOAP globale -->
<soap:binding
style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<!-- Binding de l'opération TransferFunds -->
<operation name="TransferFunds">
<soap:operation
soapAction="http://www.example.com/banking/TransferFunds"
style="document"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
<fault name="InvalidAccountFault">
<soap:fault name="InvalidAccountFault" use="literal"/>
</fault>
</operation>
<!-- Binding de l'opération GetBalance -->
<operation name="GetBalance">
<soap:operation
soapAction="http://www.example.com/banking/GetBalance"
style="document"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>Paramètres importants :
style: “document” ou “rpc”transport: Protocole de transport (HTTP, SMTP, etc.)soapAction: En-tête HTTP pour identifier l’opérationuse: “literal” (respecte le schéma) ou “encoded”
6. Service (Point d’accès)
Définit où le service est accessible (URL concrète).
<service name="BankingService">
<documentation>Service bancaire pour les opérations de compte</documentation>
<port name="BankingSOAPPort" binding="tns:BankingSOAPBinding">
<soap:address location="http://bank.example.com:8080/services/banking"/>
</port>
<!-- Peut avoir plusieurs ports pour différents bindings -->
<port name="BankingHTTPPort" binding="tns:BankingHTTPBinding">
<http:address location="http://bank.example.com:8080/api/banking"/>
</port>
</service>Éléments :
service: Conteneur pour les portsport: Point d’accès spécifiquename: Nom du portbinding: Référence au binding utiliséaddress: URL concrète du service
Exemple complet de WSDL
Service de gestion de bibliothèque avec opérations de recherche et emprunt :
<?xml version="1.0" encoding="UTF-8"?>
<definitions
name="LibraryService"
targetNamespace="http://www.example.com/library"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://www.example.com/library"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- TYPES : Définition des structures de données -->
<types>
<xsd:schema targetNamespace="http://www.example.com/library">
<!-- Type Book -->
<xsd:complexType name="Book">
<xsd:sequence>
<xsd:element name="isbn" type="xsd:string"/>
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="author" type="xsd:string"/>
<xsd:element name="available" type="xsd:boolean"/>
<xsd:element name="publicationYear" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
<!-- Type BorrowRequest -->
<xsd:complexType name="BorrowRequest">
<xsd:sequence>
<xsd:element name="userId" type="xsd:string"/>
<xsd:element name="isbn" type="xsd:string"/>
<xsd:element name="durationDays" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
<!-- Type BorrowResponse -->
<xsd:complexType name="BorrowResponse">
<xsd:sequence>
<xsd:element name="borrowId" type="xsd:string"/>
<xsd:element name="dueDate" type="xsd:date"/>
<xsd:element name="success" type="xsd:boolean"/>
</xsd:sequence>
</xsd:complexType>
<!-- Type ArrayOfBooks -->
<xsd:complexType name="ArrayOfBooks">
<xsd:sequence>
<xsd:element name="book" type="tns:Book"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</types>
<!-- MESSAGES : Définition des messages échangés -->
<!-- Messages pour SearchBooks -->
<message name="SearchBooksRequest">
<part name="keyword" type="xsd:string"/>
</message>
<message name="SearchBooksResponse">
<part name="books" type="tns:ArrayOfBooks"/>
</message>
<!-- Messages pour GetBookDetails -->
<message name="GetBookDetailsRequest">
<part name="isbn" type="xsd:string"/>
</message>
<message name="GetBookDetailsResponse">
<part name="book" type="tns:Book"/>
</message>
<!-- Messages pour BorrowBook -->
<message name="BorrowBookRequest">
<part name="parameters" type="tns:BorrowRequest"/>
</message>
<message name="BorrowBookResponse">
<part name="parameters" type="tns:BorrowResponse"/>
</message>
<!-- Message d'erreur -->
<message name="LibraryFault">
<part name="errorCode" type="xsd:string"/>
<part name="errorMessage" type="xsd:string"/>
</message>
<!-- PORTTYPE : Interface abstraite du service -->
<portType name="LibraryPortType">
<operation name="SearchBooks">
<documentation>Recherche des livres par mot-clé</documentation>
<input message="tns:SearchBooksRequest"/>
<output message="tns:SearchBooksResponse"/>
</operation>
<operation name="GetBookDetails">
<documentation>Obtient les détails d'un livre par ISBN</documentation>
<input message="tns:GetBookDetailsRequest"/>
<output message="tns:GetBookDetailsResponse"/>
<fault name="BookNotFoundFault" message="tns:LibraryFault"/>
</operation>
<operation name="BorrowBook">
<documentation>Emprunte un livre</documentation>
<input message="tns:BorrowBookRequest"/>
<output message="tns:BorrowBookResponse"/>
<fault name="BookUnavailableFault" message="tns:LibraryFault"/>
</operation>
</portType>
<!-- BINDING : Liaison avec SOAP -->
<binding name="LibrarySOAPBinding" type="tns:LibraryPortType">
<soap:binding
style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="SearchBooks">
<soap:operation
soapAction="http://www.example.com/library/SearchBooks"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="GetBookDetails">
<soap:operation
soapAction="http://www.example.com/library/GetBookDetails"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
<fault name="BookNotFoundFault">
<soap:fault name="BookNotFoundFault" use="literal"/>
</fault>
</operation>
<operation name="BorrowBook">
<soap:operation
soapAction="http://www.example.com/library/BorrowBook"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
<fault name="BookUnavailableFault">
<soap:fault name="BookUnavailableFault" use="literal"/>
</fault>
</operation>
</binding>
<!-- SERVICE : Point d'accès concret -->
<service name="LibraryService">
<documentation>
Service de gestion de bibliothèque permettant la recherche
et l'emprunt de livres
</documentation>
<port name="LibrarySOAPPort" binding="tns:LibrarySOAPBinding">
<soap:address
location="http://library.example.com:8080/services/library"/>
</port>
</service>
</definitions>Flux d’utilisation du WSDL
- Le client télécharge le WSDL
- Il génère le code client (proxy) à partir du WSDL
- Il appelle les opérations définies dans le portType
- Les messages sont formatés selon les types
- Ils sont transmis selon le binding (SOAP)
- Vers l’adresse définie dans service
Points clés à retenir
Hiérarchie logique :
Service (où ?)
└─> Port (comment accéder ?)
└─> Binding (quel protocole ?)
└─> PortType (quelles opérations ?)
└─> Operations (quel flux ?)
└─> Messages (quelles données ?)
└─> Types (quelle structure ?)
Parties abstraites (réutilisables) :
- types
- message
- portType
Parties concrètes (spécifiques) :
- binding
- service
Exercice : Écrire un WSDL
Service météo avec deux opérations :
- GetCurrentTemperature(city: string) : decimal
- GetForecast(city: string, days: int) : ArrayOfForecast
<?xml version="1.0" encoding="UTF-8"?>
<definitions
name="WeatherService"
targetNamespace="http://www.example.com/weather"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://www.example.com/weather"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<types>
<xsd:schema targetNamespace="http://www.example.com/weather">
<xsd:complexType name="Forecast">
<xsd:sequence>
<xsd:element name="date" type="xsd:date"/>
<xsd:element name="minTemp" type="xsd:decimal"/>
<xsd:element name="maxTemp" type="xsd:decimal"/>
<xsd:element name="condition" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ArrayOfForecast">
<xsd:sequence>
<xsd:element name="forecast" type="tns:Forecast"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</types>
<message name="GetCurrentTemperatureRequest">
<part name="city" type="xsd:string"/>
</message>
<message name="GetCurrentTemperatureResponse">
<part name="temperature" type="xsd:decimal"/>
</message>
<message name="GetForecastRequest">
<part name="city" type="xsd:string"/>
<part name="days" type="xsd:int"/>
</message>
<message name="GetForecastResponse">
<part name="forecasts" type="tns:ArrayOfForecast"/>
</message>
<portType name="WeatherPortType">
<operation name="GetCurrentTemperature">
<input message="tns:GetCurrentTemperatureRequest"/>
<output message="tns:GetCurrentTemperatureResponse"/>
</operation>
<operation name="GetForecast">
<input message="tns:GetForecastRequest"/>
<output message="tns:GetForecastResponse"/>
</operation>
</portType>
<binding name="WeatherSOAPBinding" type="tns:WeatherPortType">
<soap:binding
style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="GetCurrentTemperature">
<soap:operation
soapAction="http://www.example.com/weather/GetCurrentTemperature"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="GetForecast">
<soap:operation
soapAction="http://www.example.com/weather/GetForecast"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="WeatherService">
<port name="WeatherSOAPPort" binding="tns:WeatherSOAPBinding">
<soap:address location="http://weather.example.com/services/weather"/>
</port>
</service>
</definitions>