How-to : Les web services en Java 6
Pourquoi faire un web service ? A quel moment ?
Le besoin de web service apparaît lorsque l’on veut faire communiquer plusieurs applications et que :
- nous nous trouvons dans un environnement hétérogène (environnement faisant intervenir des technologies différentes)
- ou bien dans un environnement homogène mais que l’on veut assurer un couplage faible entre les applications.
Le choix entre “REST” ou “SOAP” n’est pas qu’un choix technologique, un phénomène, de mode ou une préférence, il est induit par l’architecture du projet et les contraintes techniques imposées par l'environnement.
Dans une SOA, une architecture orientée service, nous manipulerons les objets (Document) qu’à travers des processus. La combinaison SOAP/WSDL répond aux besoins d’une telle architecture.
L’accès à un document ne se fait qu’à travers un appel de service.
Dans une ROA, architecture orientée ressource, la manipulation des objets (Resource) sera déléguée au consommateur du service. REST propose en somme de faire du CRUD sur un objet.
L’accès à une ressource se fait en pointant directement sur son URI.
Dans un contexte où les clients sont des navigateurs ou des terminaux mobiles, nous préférerons l’utilisation de REST car il s’avèrera plus léger au niveau du trafic réseau (dans la plupart des cas).
En SOAP
Contract First ou Java First ?
Le WSDL (généralement prononcé “wizdeul”) fournit par un service SOAP est sa description.
On y trouve la description des objets manipulés (types), l’interface du service (portTypes) et sa localisation (service).
“Contract First” signifie que le développeur commence par décrire son service en rédigeant un WSDL. Il va ensuite générer le code à partir de ce WSDL.
“Java First” (ou “Code First”) signifie que le développeur va commencer par implémenter le service et générer par la suite le WSDL qui lui correspond.
Il est clairement préférable d’utiliser la méthode Contract First.
La rédaction du WSDL permet :
- de réfléchir sur les documents qui seront manipulés. (quels sont-ils ? seront-ils utilisés par d’autre services ?),
- de décrire l’interface du service et mettre à plat les besoins auxquels devront répondre ce service,
- de documenter le service.
Une fois que le WSDL est validé, le code peut être généré.
En java, les stub et skeleton peuvent être générés à partir d’un WSDL.
Comment savoir que mon WSDL est correctement écrit ?
Deux conditions pour qu’un WSDL soit valide :
- que le XML soit valide. N’importe quel éditeur XML permet de le vérifier,
- qu’il passe le test WS-I Basic Profile ce qui vous assurera que le WSDL pourra être interprété par les frameworks propriétaires adhérants à la WS-I Organisation ainsi que la plus part des frameworks open-source.
A partir de quand peut on considérer que le WSDL est exploitable et diffusable ?
A partir du moment où celui-ci est validé et après avoir vérifié que le framework choisi est capable de générer le code, juste pour être sur :).
Doit on faire le mock en parallèle ?
Comme vu précédemment, avant de diffuser le WSDL, il est préférable de vérifier que la génération se passe correctement. Pour cela une fois le code généré, il convient d'implémenter un mock du service avec le skeleton généré et de le l'interroger avec le stub généré.
Les objets doivent-ils être inclus dans le contrat ?
Dans un WSDL, les documents manipulés doivent être déclarés entre les balises <wsdl:types>...</wsdl:types>. Le schéma peut être directement déclarer ici ou bien être importer à partir d’un document xsd via la balise <xsd:import/>.
La question à se poser pour savoir si les documents doivent être définis dans le contrat est : “les documents seront ils partagés avec d’autres services de mon SI (ou à moindre échelle, d’autres services de mon application) ?”
Dans le cas où plusieurs services utilisent les mêmes documents, il convient de créer un schéma XSD séparé, et de publier ce schéma afin qu’il soit accessible par tous les acteurs.
Comment chiffrer un WSDL pour le vendre au client ?
Tout dépend de l’intégration du service dans l’écosystème du SI.
- S’il ne manipule pas de documents en commun avec d’autres services, sa rédaction sera relativement simple. Les types pourront être intégrés au contrat. Il n’y aura donc qu’un seul livrable, le WSDL.
- Dans le cas ou le service utilise des documents en commun avec d’autres services, et que ces documents existent déjà, il faudra chiffrer uniquement le contrat.
- Enfin dans le cas ou les documents manipulés doivent être prévus pour être utilisés par d’autres services et que ces documents n’existent pas encore, il sera nécessaire, comme dans le premier cas, de chiffrer le contrat et les documents. Cependant la rédaction des documents demandera beaucoup plus d’analyse et une vue d’ensemble du SI.
Le WSDL doit-il être fait en phase de développement ou pendant les spécifications ?
Si le client est assez ouvert, il peut faire partie des spécifications, car c’est un document très complet. Toutefois, plus le fonctionnel est compliqué plus les documents et le contrat qui seront utilisés seront complexes. Ils nécessiteront une analyse qui pourrait exploser le chiffrage des spécifications.
Quels outils utiliser ?
Pour rédiger les WSDL et XSD il est nécessaire d’avoir un éditeur XML permettant de valider les documents. La validité doit se faire au niveau de la syntaxe XML et de WS-I Basic Profile. L'éditeur XML inclus dans Eclipse permet de faire ceci, par défaut la validation WS-I Basic Profile ne lève que des warnings, il est préférable de lever le niveau en erreur afin que le document ne soit pas validé s’il ne respecte pas ce standard.
Quel Framework utiliser ?
Actuellement, dans le monde opensource (et gratuit) java, trois frameworks se partagent le marché : Metro, CXF, Axis 2.
- Metro évolue au sein du projet Glassfish server, qui est l’implémentation de référence JEE. Il peut cependant être installé sur Tomcat,
- CXF est maintenu par Apache,
- Axis 2 est lui aussi maintenu par Apache.
Tous trois s’appuient sur jax-ws et jaxb pour la gestion des web services et le binding XML.
Ils différent cependant sur beaucoup de choses.
Les outils de génération de code :
- Metro utilise les outils du jdk. Celui génère les interfaces à implementer coté serveur, ainsi que le stub,
- CXF propose par exemple, en plus de ça, de générer le skeleton de l’application, ce qui fait gagner un temps considérable.
Les couches de haut niveau (Transport, Reliability, Transaction, Security) sont implémentés différemment dans chacun des frameworks. Par exmple pour WS-Security :
- Metro se base sur XWSS,
- CXF sur WSS4J,
- Axis 2 sur Rampar.
La plus part du temps vous n’aurez pas à aller jusqu'à la mise en place de ces couches.
Comment passer des paramètres en soap ?
Idéalement les paramètres de nos opérations seront les types décrits dans le contrat.
De plus les opérations ne prendront qu’un seul paramètre.
Les informations utiles que l’opération tirera du type passé en paramètre seront décrites dans la documentation de l’opération.
Par exemple, si nous avons un article défini avec ces propriétés :
- uuid
- label
- price
- type
Nous pourrons décrire une opération de recherche d’article comme ceci :
searchArticles(Article article)
Dans la documentation il suffit de préciser comment le service réagit:
searchArticles renvoie les articles correspondant aux propriétés suivantes présente dans l’article passé en paramètre : uuid, label et type.
Il faut éviter absolument la prolifération d'opération de type :
- searchArticlesByLabel(String label)
- searchArticlesByType(Type type)
- getArticleByUuid(String uuid)
Comment bien documenter mon WSDL ?
Il faut déjà commencer par bien documenter les xsd utilisés. Pour cela utiliser la balise <xsd:documentation>. Comme pour la java, où il est nécessaire de documenter la classe et chaque propriété, ici il faut documenter le schéma et chaque élément qui le compose.
Dans le WSDL, il convient de commenter chaque élément déclaré, ainsi que chaque opération dans la partie <wsdl:portType></wsdl:portType> et dans chaque opération, chaque élément qui la compose (input, output, fault ).
Mes XSD doivent-ils représenter mon modèle de donnée ?
Non, la façon dont sont persistées les données ne doit pas influencer le design du document publié.
Pour commencer les contraintes ne sont pas les mêmes comme par exemple celles imposées par les 5 formes normales d’un modèle de donnée.
De plus il arrivera certainement que le document soit généré à partir de l'agrégation de plusieurs objets qui peuvent parvenir de plusieurs sources de données.
Par contre la démarche inverse peut être utilisée (top-down). On commence par concevoir schéma du document (besoin fonctionnel) et une fois établie on étudie sa persistance (technique).
Comment instancier mes objets générés par les outils d’importation ?
Quelque soit le framework utilisé celui-ci doit (ou devrait) se baser sur jaxws et jaxb.
Les objets jaxb sont un peut particulier, c’est pourquoi à la génération du code une classe Factory est générée. Cette classe propose des méthodes pour instancier tous les objets manipulés. Il faut absolument éviter d’instancier des objets jaxb manuellement.
Par exemple en admettant que vous manipuliez un objet Task dans vos XSD une classe homonyme sera générée en java.
Dans votre code il ne faudra jamais utiliser le constructeur implicite de Task comme ceci.
Task myTask = new Task();
Mais comme cela.
ObjectFactory myFactory = new ObjectFactory();
Task myTask = myFactory.createTask();
En REST
Comment doit se présenter une URl ?
L’URI défini l’emplacement d’une ressource. Elle doit représenter une hiérarchie (comme pour les répertoires) et être facilement compréhensible par tout le monde afin qu’elle soit réutilisée (n’oublions pas que le but est de publier des ressources).
Elle ne doit pas comprendre de caractère sensible à l’URL encoding. Par exemple le caractère espace est remplacé par %20s, il est donc préférable d’utiliser des tirets. De plus éviter une case mixte, garder les caractères minuscules.
Par exemple :
A eviter :
http://www.music.com/Discs/French%20Touch/
Recommandé :
http://www.music.com/discs/french-touch/
Placer vos ressources dans des répertoires dont le nom indique un pluriel (notion de liste)
http://monsite.ecomerce.com/artcles/article-1
Ainsi, pour trouver les articles selon un critère nous ferons ainsi :
http://monsite.ecomerce.com/artcles/?name=bisounours
Afin pour retrouver des ressources attachées à une autre ressource:
http://monsite.ecomerce.com/artcles/article-1/advices
Ici nous récupérerons tout les avis utilisateurs associés à l’article 1.
Quel est le format d’échange approprié ?
Si les consommateurs identifiés du service sont uniquements des navigateurs, alors JSON est à favoriser, JSON étant le format de sérialisation natif Javascript.
Dans la cas ou d’autres consommateurs sont identifiés, le xml devra être utilisé étant donné que c’est un format d’échange standard.
Quel Framework ?
Des Servlets peuvent suffire la plupart du temps.
Sinon il existe tout de même des framework :
- Jersey, l’implémentation de référence se trouvant dans GlassFish server. Il s'appuie sur jax-rs.
- CXF qui s’appuie aussi sur jax-rs,
- Restlet,
- RESTEasy
- …
Commentaires
Enregistrer un commentaire