Web Services avec PHP5 : SOA

Vivien Brissat

Les Services WEB, représentant l'architecture SOA (Service-Oriented Architecture), sont simples à utiliser avec PHP, et offrent un réel intérêt lorsqu'il s'agit de faire fonctionner des environnements hétérogènes.

Cet article montre comment mettre en œuvre simplement un Service WEB via l'API SOAP de PHP, comment "consommer" du Service WEB, et comment trouver des Services WEB existants.

- Titre : Web Services avec PHP5 : SOA

- Auteur : Vivien Brissat

- Parution : 25 février 2008

- Licence : Copyright ® 2008 Vivien Brissat. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Web services : Késako ?

- II. Qu'est-ce que SOAP, et que fait-il dans les Services WEB

- III. WSDL : Description d'un Service

- IV. PHP5 et son API intégrée SOAP

- IV-A. Exemple de consommation de Service WEB via le client SOAP PHP

- IV-B. Exemple de Service WEB via le serveur SOAP PHP

- V. Conclusion

I - Web services : Késako ?

Un Service WEB est un ensemble de protocoles permettant à des applications de communiquer entre elles, et ce indépendamment de la structure et du langage employés.

En effet, dans une application communiquante il existe 2 types de couplages :

- Le couplage fort (c'est en général les types d'interactions natives, par exemple une interface graphique couplée aux contrôleurs dans une architecture MVC) ;

- Le couplage faible, dans lequel interviennent les Services WEB (En général, il s'agit de la communication entre 2 composants physiquement séparés). Dans le cas d'un couplage faible, on parlera aussi d' « Architecture Orientée Service » (SOA), qui permet de rendre des composants applicatifs disponibles via un service, la plupart du temps un ou des Services WEB. (On nommera par exemple l'ensemble de Services WEB Google, qui est typiquement un SOA).

Les Services WEB sont un avantage certain notamment pour diversifier la façon de servir des données : en effet, on peut très bien imaginer une application présentant une interface graphique formatée et, par l'intermédiaire de Services WEB, permettre l'interfaçage avec d'autres types de médias.

Pour les méthodes de communications utilisées pour établir ou "consommer" un Service WEB, nous noterons :

- Le protocole RPC (Remote Procedure Call), ancêtre de SOAP et qui a donné lieu à XML-RPC et JSON-RPC : il permet à des processus issus d'environnements hétérogènes de faire appel à des procédures distantes via un protocole de communication (HTTP, SMTP...),

- REST (Representational State Transfert), qui n'est pas un protocole au même titre que RPC, mais une architecture définie par des règles « simples » facilitant l'accès à ces services et basé sur HTTP.

- SOAP, ou Simple Object Access Protocol, qui autorise des objets à faire des appels à des méthodes issues d'autres objets la plupart du temps physiquement séparés (serveurs distants). SOAP utilise le plus souvent HTTP comme protocole de communication, mais il peut aussi utiliser d'autres protocoles comme SMTP.

Nous utiliserons SOAP comme base dans le reste de l'article, car l'un des plus répandus pour réaliser des Services WEB, et géré en natif par PHP 5.

REST est aussi beaucoup utilisé, et représente une approche des Services WEB moins « stricte » que SOAP car il repose entièrement et uniquement sur HTTP. Les Services WEB d'Amazon par exemple sont en REST.

II - Qu'est-ce que SOAP, et que fait-il dans les Services WEB

Fonctionnement de SOAP pour la fourniture de Service WEB

SOAP est un protocole RPC (Remote Procedure Call) orienté objet permettant de communiquer et d'échanger des messages.

Ainsi, il permet la communication et la transmission de messages entre 2 objets distants, autorisant l'appel à des méthodes servies par un Service WEB.

Lors d'un échange SOAP, le message transmis se décompose en 2 parties :

1. L'enveloppe, qui contient toutes les informations relatives au contenu du message ;

2. Le contenu lui-même qui est formé de données structurées (méthodes formatées, interrogation structurée d'après les besoins du serveur, etc.).

Un message SOAP repose sur les technologies XML, ce qui permet une interopérabilité totale entre systèmes (cf. les tutoriels XML). XML décrit les bases de SOAP, cœur du Service WEB. À noter que SOAP peut communiquer sur différents protocoles de communication, tels HTTP ou SMTP (ce qui représente un avantage : le port 80 des firewalls est souvent ouvert, ce qui permet de ne pas modifier les règles de sécurité dans une entreprise). Par ailleurs, SOAP est régi par des normes du W3C.

III - WSDL : Description d'un Service

Nous avons un protocole d'échange entre 2 objets distants, nous avons un serveur de Service WEB et nous voulons consommer... Mais comment savoir ce que l'on peut consommer, et de quelle manière ? La description WSDL répond à cette question.

WSDL signifie Web Services Description Language et doit être fourni par le fournisseur du Service WEB (le serveur). Il est possible de s'en passer, mais alors la fourniture du Service WEB risque d'être difficile, ne sachant pas ce que l'on peut faire avec !!!

Le fichier WSDL est en XML et il permet de décrire l'utilisation complète du service. C'est en fait un mode d'emploi, ni plus ni moins, et il permettra à de nombreux programmes ou même langages de programmation de découvrir automatiquement un service, voire de gérer les modalités d'échanges SOAP (port d'échange, protocole, encodage, etc.), on pourrait presque le comparer à la DTD d'un fichier XML (Zend Studio et DIA permettent la réalisation assistéee d'un tel fichier, sinon on peut se servir des spécifications W3C pour l'écrire à la main).

IV - PHP5 et son API intégrée SOAP

PHP5 intègre d'origine une API SOAP permettant de créer des serveurs ou des clients, et ce de façon très simplifiée.

En effet, PHP5 interprète de façon transparente les fichiers WSDL lors de la déclaration d'un client à un Service WEB, et gère lui-même le formatage SOAP des messages envoyés au serveur : formatage XML, respect des règles du WSDL...

Le serveur SOAP de PHP propose les mêmes facilités que pour le client, hormis pour la description WSDL qui doit être réalisée par un autre biais. Dans ce cas, le serveur « sert » le Service WEB selon les spécificités décrites dans le WSDL.

IV-A - Exemple de consommation de Service WEB via le client SOAP PHP

Dans cet exemple, nous allons nous connecter à un Service WEB fourni par un annuaire de Services WEB : http://www.xmethods.net. Leur Service WEB est très simple à mettre en œuvre, et permet de récupérer une liste de Services WEB proposés. Pour plus d'infos, allez sur http://www.xmethods.net/ve2/Interfaces.po, qui décrit les méthodes accessibles.

Le fichier WSDL de description du service permet à PHP d'interpréter le type de message à envoyer, par quels moyens et, le cas échéant, de renvoyer un message d'erreur (ce message peut être renvoyé par le serveur, mais aussi par le client si la méthode a mal été invoquée).

Pour avoir un exemple de fichier WSDL, allez voir l'exemple utilisé ici : http://www.xmethods.net/interfaces/query.wsdl.

Pour plus d'informations sur les spécificités de la classe client SOAP de PHP, rendez-vous sur la documentation.

Client SOAP en PHP

<?php
/**
* Invocation simple à un Service WEB : la classe SoapClient() comporte des paramètres supplémentaires
* qui seront intéressants à étudier dans la documentation
*/

//On doit passer le fichier WSDL du Service en paramètre de l'objet SoapClient()
$wsdl="http://www.xmethods.net/wsdl/query.wsdl";
$service=new SoapClient($wsdl);

//À partir de là, on peut déjà faire appel aux méthodes du service décrites dans le WSDL
$taballservices=$service->getAllServiceSummaries();

//On renvoie le résutat de notre méthode, pour voir....
print_r($taballservices);

Vous voyez d'après notre exemple qu'il est relativement facile de consommer un Service WEB grâce à PHP5 et son API SOAP !!!! L'exemple utilisé est simple, il existe une multitude de Services WEB accessibles sur Internet, et souvent plus complexes que celui-ci : à vous de les découvrir !!! Pour cela, il existe des annuaires spécialisés, des annuaires UDDI comme celui employé dans notre exemple : xmethods.net.

Beaucoup de Services WEB sont payants et demandent une inscription spéciale au service ; il vous sera alors fourni des instructions pour y accéder en toute sécurité (méthode de Login/Password, clé unique à insérer en paramètre du Client SOAP, etc.).

IV-B - Exemple de Service WEB via le serveur SOAP PHP

Maintenant que nous savons consommer du Service WEB, passons au Serveur SOAP.

Nous allons prendre un exemple des plus simples, dans le but d'alléger l'article : nous assurons ici la simplicité de la mise en œuvre.

Nous allons donc créer un Service WEB qui retournera la date du serveur ainsi que sa signature. Voyez la simplicité ;)

Commencons par la classe à mettre en place :

Classe de test pour le serveur SOAP

<?php
/**
* Classe qui va nous servir à tester le serveur SOAP : il s'agit d'une classe classique...
*
*/

class DateServeur{

function retourDate(){

$serveur=$_SERVER['SERVER_SIGNATURE'];
$date=date("d/m/Y");

$tab['serveur']=$serveur;
$tab['date']=$date;

return $tab;
}
}

Continuons notre exemple, avec la formation du fichier WSDL décrivant notre futur Service WEB : j'utilise Zend Studio qui me permet de créer très simplement les fichiers WSDL, mais vous pouvez utiliser DIA ou bien l'écrire à la main. Pour avoir des informations sur la synthaxe à utiliser, rendez-vous sur http://www.w3.org/TR/wsdl

Déclaration du fichier WSDL de description du service

<?xml version='1.0' encoding='UTF-8'?>

<!-- WSDL file generated by Zend Studio. -->

<definitions name="exemple" targetNamespace="urn:exemple" xmlns:typens="urn:exemple" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:typens0="http://192.168.0.19/experiences/essai_instance.php">
<message name="retourDate"/>
<message name="retourDateResponse">
<part name="retourDateReturn"/>
</message>
<portType name="essai_instancePortType">
<operation name="retourDate">
<input message="typens:retourDate"/>
<output message="typens:retourDateResponse"/>
</operation>
</portType>
<binding name="essai_instanceBinding" type="typens:essai_instancePortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="retourDate">
<soap:operation soapAction="urn:essai_instanceAction"/>
<input>
<soap:body namespace="urn:exemple" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</input>
<output>
<soap:body namespace="urn:exemple" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</output>
</operation>
</binding>
<service name="exempleService">
<port name="essai_instancePort" binding="typens:essai_instanceBinding">
<soap:address location="http://192.168.0.19/experiences/essai_instance.php"/>
</port>
</service>
</definitions>

Une fois le fichier WSDL formé, il faut déclarer le Serveur SOAP :

Déclaration complète du serveur SOAP PHP

<?php
/**
* Déclaration d'une classe qui contiendra les méthodes de Service WEB, et instanciation de la classe SoapServer
* pour rendre notre Service disponible
*
*/

//Cette classe pourra contenir d'autres méthodes accessibles via le SoapServer
class DateServer{

//On déclare notre méthode qui renverra la date et la signature du serveur dans un tableau associatif...
function retourDate(){

$tab = array(
'serveur' => $_SERVER['SERVER_SIGNATURE'],
'date' => date("d/m/Y")
);

return $tab;
}
}

//Cette option du fichier php.ini permet de ne pas stocker en cache le fichier WSDL, afin de pouvoir faire nos tests
//Car le cache se renouvelle toutes les 24 heures, ce qui n'est pas idéal pour le développement
ini_set('soap.wsdl_cache_enabled', 0);

//L'instanciation du SoapServer se déroule de la même manière que pour le client : voir la doc pour plus d'informations sur les
//Différentes options disponibles
$serversoap=new SoapServer("http://192.168.0.19/experiences/exemple.wsdl");

//Ici nous déclarons la classe qui sera servie par le Serveur SOAP, c'est cette déclaration qui fera le coeur de notre Servie WEB.
//Je déclare que je sers une classe contenant des méthodes accessibles, on peut aussi déclarer plus simplement des fonctions
//par l'instruction addFunction() : $serversoap->addFunction("retourDate"); à ce moment-là nous ne faisons pas de classe.

//Noter le style employé pour la déclaration : le nom de la classe est passé en argument de type String, et non pas de variable...
$serversoap->setClass("DateServer");

//Ici, on dit très simplement que maintenant c'est à PHP de prendre la main pour servir le Service WEB : il s'occupera de l'encodage XML, des
//Enveloppes SOAP, de gérer les demandes clientes, etc. Bref, on en a fini avec le serveur SOAP !!!!
$serversoap->handle();

Simple, non ?! N'oubliez pas de consulter la documentation, très complète. En effet, il existe de nombreuses fonctionnalités disponibles pour la classe SoapServer, à vous de les découvrir : ce document a en effet pour vocation de vous présenter les Services WEB et leurs possibilités avec PHP5...

Maintenant que nous avons formé notre premier Service WEB, il faut déclarer un client pour pouvoir le consommer : on reprendra donc notre script plus haut, afin de l'adapter pour notre service. Vous devriez donc arriver à cela :

Déclaration d'un client SOAP pour consommer notre Service WEB

<?php
/**
* Invocation du Service WEB que nous venons de créer
*/

//Cette option permet d'éviter la mise en cache du WSDL, qui se renouvelle toutes les 24 heures... Pour le développement, ce n'est pas génial !!!
ini_set('soap.wsdl_cache_enabled', 0);

//On doit passer le fichier WSDL du Service en paramètre de l'objet SoapClient
$service=new SoapClient("http://192.168.0.19/experiences/exemple.wsdl");

//On accède à la méthode de notre classe DateServeur, déclaré dans notre SoapServer
$taballservices=$service->retourDate();

//On renvoie le résutat de notre méthode, pour voir...
print_r($taballservices);

L'adresse de mon fichier WSDL correspond à mon propre serveur, n'oubliez pas de la changer... ;)

Si tout se passe bien, le client SOAP vous renverra un tableau associatif contenant la date et la signature du serveur.

V - Conclusion

Ces petits exemples vous ont permis d'aborder les concepts liés aux Services WEB, autant pour la consommation que pour les servir. Si vous désirez aller plus loin (et nul doute que vous le voulez : l'architecture SOA est très attirante), je ne peux que vous conseiller la documentation officielle, un annuaire UDDI et un peu de temps libre. Il serait dommage de passer à côté de ce style de service alors que PHP5 nous permet une telle simplicité d'utilisation !!!

Le plus difficile à mon avis, reste l'écriture du fichier WSDL. Les logiciels les écrivant automatiquement sont encore rares, peu pratiques ou alors coûteux.

L'architecture SOA a notamment pour but de réunir des technologies hétérogènes autour de standards, en l'occurrence SOAP et XML. On peut envisager dès lors de faire fonctionner ensemble, par exemple : une application écrite en PHP (logique applicative, accès en base de données) et via les Services WEB lier une interface graphique de type RIA (Rich Internet Application) telle Flex ou bien Open Laszlo afin d'en présenter le résultat.