Informatique Repartie Chapitre 5 : Web Services ‐ REST Cecilia Zanni‐Merk cecilia.zanni‐merk@insa‐rouen.fr Bureau BO B R1 04 Basé sur le cours de M Alexandre Pauchet, INSA Rouen Normandie, 2016 Références • Le cours de M Pauchet sur Moodle • Architectures réparties en Java de Annick Fron ISBN 9782100738700. Ed Dunod 2 Références et cours sur le Web • The Java EE 6 tutorial http://docs.oracle.com/javaee/6/tutorial/doc/index.html • Cours Sun http://miageprojet2.unice.fr/@api/deki/files/99/=FY09TechDays_RES T_Carol_(1).odp • Cours M. Baron http://mbaron.developpez.com/soa/jaxrs/ • JSR311 http://jcp.org/en/jsr/summary?id=311 3 Architectures : Rappel • Années 70 : architectures Mainframe (1 tier) • Années 80 : architectures 2 tiers (BD) • Fin des années 80 : architectures 3 tiers (RPC) • Années 90 : architectures 3 tiers Objet (RMI/Corba) • Années 00 : architectures orientées services (Web Services) • Fin des années 00 : architectures orientées ressources (RESTful) 4 Web Services : Rappel • Sur le plan conceptuel, un service est une composante logicielle fournie via un point d’attache (endpoint) accessible au réseau. • Sur le plan technique, les services Web peuvent être mis en œuvre de diverses façons. • services Web «étendus» (« big » dans la littérature), implémentés avec JAX‐ WS XML, SOAP, WSDL • services Web «RESTful», implémentés avec JAX‐RS RESTful = Representational State Transfer Mieux intégrés avec HTTP que SOAP, ils n’ont pas besoin de messages XML ou de définitions WSDL 5 Cours de Mickael Baron « Comprendre le style d’architecture REST » 6 SOAP Avantages Standardisé Interopérabilité Sécurité Outillé Inconvénients Performances (enveloppe SOAP supplémentaire) Complexité Cible l’appel du service REST Avantages Simplicité de mise en œuvre Lisibilité par l’humain Inconvénients Sécurité restreinte par l’emploi des méthodes HTTP Cible uniquement l’appel de ressource Evolutivité Repose sur les principes du Web Représentations multiples 7 Quand utiliser les WS RESTful ? • Les services REST ne gardent pas d’état • Une infrastructure de mise en cache peut être exploitée en fonction des performances. • Le producteur et le consommateur des services ont une compréhension mutuelle du contexte et du contenu transmis. • La bande passante est particulièrement importante et doit être limitée. • La prestation de services Web ou leur agrégation dans des sites Web existants peut être activée facilement avec un style RESTful. 8 Les services web RESTful 9 Description • REST (Representational State Transfer) est un style architectural qui spécifie des contraintes, telles qu’une interface uniforme, qui permettent aux services de travailler le mieux sur le Web. • Dans le style architectural REST, les données et les fonctionnalités sont considérées comme des ressources et sont accessibles à l'aide d'URI (Uniform Resource Identifiers) • Les ressources sont exploitées en utilisant un ensemble d'opérations simples et bien définies, sur un protocole de communication sans état, généralement HTTP • Les clients et les serveurs échangent des représentations de ressources en utilisant une interface et un protocole normalisés. 10 Caractéristiques • Identification de ressources via des URIs : Le service web expose un ensemble de ressources (via leur URI) pour identifier les cibles de l’interaction avec leur clients • Une interface uniforme : Les ressources sont manipulés exclusivement avec 4 méthodes PUT, GET POST et DELETE • Des messages auto‐descriptifs : Les ressources sont séparées de leur représentation (leur contenu peut être obtenu dans divers formats, HTML, XML, texte, PDF, JPEG, JSON, ou d’autres) • Interactions à états (statful) grâce aux hyperliens : chaque interaction avec une ressource est sans état (les requêtes sont auto‐contenues, l’état est maintenu par la représentation de la ressource). Les interactions à états se basent sur un transfert d’état explicit Simplifie le service mais augmente le volume de la communication !! 11 Requête REST • Ressource (identifiant) • Identifiée par une URI • Ex : http://localhost:8080/SecretariatREST/plan • Méthode • Elles permettent de manipuler les identifiants • Méthodes HTTP : GET, POST, PUT et DELETE • Représentation • Vue sur l‘état (requête client/serveur) • Ex : XML, JSON 12 Ressource et URI Une ressource est un objet ou plusieurs objets auquel les utilisateurs du service peuvent vouloir accéder. • Une URI identifie une ressource de manière unique • Une ressource peut avoir plusieurs URI et la représentation de la ressource peut évoluer avec le temps • Les ressources sont hiérarchiques : une ressource peut être une collection de ressources • Exemples http://localhost:8080/banque/comptes/BobLeponge/PEL http://localhost:8080/banque/comptes/BobLeponge/1 • /PEL et /1 sont les identifiants primaires d'une même ressource • /banque/comptes/BobLeponge est une ressource de type collection : tous les comptes de BobLeponge 13 Ressource, opération et méthode HTTP • Operations • Une ressource peut subir 4 opérations (CRUD) : Create (Création), Retrieve (Lecture), Update (Mise a jour), Delete (Suppression) • Méthodes HTTP. Chaque opération correspond a une méthode HTTP : • • • • Create POST Retrieve GET Update PUT Delete DELETE 14 Les requêtes HTTP 15 Plus sur les méthodes • Les méthodes HTTP sont toujours des verbes en majuscules. • GET : Récupère des données d'une ressource. • POST : Envoie des données dans une requête, en général, pour l’ajouter à la ressource qui apparaît dans l’URI de la première ligne • PUT : plus restrictif que POST, ne laisse pas le choix au serveur de décider où affecter les données C’est pour cela que on parle, en général, de modifications • DELETE : pour supprimer la ressource donnée dans l’URI 16 Les réponses 17 Représentations • Objectif : fournir les données suivant une représentation pour • le client (GET) • le serveur (PUT et POST) • Les données peuvent être retournées dans différents formats (XML, HTML, JSON, etc.) • Les formats des requêtes et des réponses peuvent être différents 18 Les codes HTTP • Lors de l’accès à une ressource, un code numérique est reçu avec le message Selon le code HTTP reçu, l’application • Les codes HTTP sont toujours trois chiffres et sont catégorisés en client peut décider quoi faire après. Par fonction du chiffre des centaines. exemple si un serveur répond avec un • 2xx indique le succès. code 500, le client ne pourra pas • 3xx redirige le client ailleurs. assigner les données anticipées à une • 4xx indique une erreur de la part du client. variable. Par contre avec un code 200, le • 5xx indique une erreur de la part du serveur. client saura que la réponse était bonne et qu’il pourra procéder à l’interprétation des informations 19 reçues ! Premiers tests • D’abord, il nous faut un outil pour l’émission de requêtes HTTP • Le plugin Poster disponible sous Firefox • Curl (https://curl.haxx.se/) 20 Exemple : Google URL Shortener • Google URL Shortener est un service de réduction d’URL code.google.com/apis/urlshortener/ • Actions proposées • Réduire une URL en un URL plus courte (POST) • Retrouver une URL longue à partir d’une URL courte (GET) • Afficher les statistiques sur l’utilisation d’une URL réduite (GET) • Service gratuit et proposant une API REST pour le développement • Pour utiliser l’API, besoin d’une clé pour certaines actions 21 Réduction d’un URL (requête et réponse) • Pour réduire l’URL http://www.google.com/ • Il faut envoyer la requête POST https://www.googleapis.com/urlshortener/v1/url Content-Type: application/json {"longUrl": "http://www.google.com/"} clé 22 Reconstruire une URL réduite • Pour reconstruire l’URL http://goo.gl/fbsS • Il faut envoyer la requête GET https://www.googleapis.com/urlshortener/v1/url?shortUrl= http://goo.gl/fbsS • Qui devrait donner comme résultat (dans le corps de la réponse) { "kind": "urlshortener#url", "id": "http://goo.gl/fbsS", "longUrl": "http://www.google.com/", "status": "OK" } 23 Google Maps Geocoding API • Le géocodage est le processus qui permet de convertir des adresses en coordonnées géographiques (latitude, longitude) • Il existe aussi le géocodage inversé https://developers.google.com/maps/documentation /geocoding/intro 24 Google Maps Geocoding API • Par exemple, our obtenir des informations sur l’adresse Place de la Cathédrale à Rouen, il faut envoyer la requête GET http://maps.googleapis.com/maps/api/geocode/jso n?address=Place+de+la+Cathédrale,+Rouen,+France &sensor=false 25 Google Maps Geocoding API 26 Tester un service REST avec SoapUI • Créer un nouveau projet REST et indiquer l’URI • SoapUI extrait les arguments de la requête, qu’on peut exécuter 27 Premier client Java • En utilisant les bibliothèques intégrées pour les clients HTTP, pour envoyer des requêtes GET et POST • java.net.URL • java.net.HttpURLConnection 28 Autre client basique (requête POST) 29 Autres API REST disponibles à explorer • Instagram https://www.instagram.com/developer/ • Gmail https://developers.google.com/gmail/api/ • GitHub https://developer.github.com/ 30 JAX‐RS 31 Description • JAX‐RS : Java API for RESTful Web Services • Spécification : JSR311 • JAX‐RS est intégré à Java à partir de Java EE 6 • Le développement de Services Web REST avec JAX‐RS s'appuie sur les annotations Java • Plusieurs implémentations existent : JERSEY (Oracle, référence), CXF (Apache), RESTEasy (JBoss/WildFly), RESTlet • La spécification ne décrit que la partie serveur, la partie client dépend de chaque implémentation 32 © M. Baron 33 Développement • Le développement de Services Web avec JAX‐RS est basé sur des POJO en utilisant des annotations spécifiques à JAX‐RS • Pas de description requise dans des fichiers de configuration • Seule la configuration d’une Servlet « JAX‐RS » est requise pour réaliser le pont entre les requêtes HTTP et les classes Java annotées • Un Service Web REST est déployé dans une application Web 34 Développement • Contrairement aux Services Web de type SOAP il n’y a pas de possibilité de développer un service REST à partir du fichier de description WADL • Seule l’approche Bottom / Up est disponible • Créer et annoter un POJO • Compiler, Déployer et Tester • Possibilité d’accéder au document WADL • Le fichier de description WADL est généré automatiquement par JAX‐ RS • Eventuellement, il est possible d’utiliser le WADL pour générer le client 35 Deux concepts de base • Les classes définissant des ressources appelées racine (root resource classes) sont • Des POJO • Soit annotées avec @Path • Soit comportent au moins une méthode annotée avec @Path ou un descripteur de méthode de requête, tel que @GET, @PUT, @POST ou @DELETE. • Les méthodes de ressources sont • Des méthodes d'une classe de ressource • Annotées avec un descripteur de méthode de requête. 36 Annotation @Path Description The @Path annotation’s value is a relative URI path indicating where the Java class will be hosted: for example, /helloworld. You can also embed variables in the URIs to make a URI path template. For example, you could ask for the name of a user and pass it to the application as a variable in the URI: /helloworld/{username}. @GET The @GET annotation is a request method designator and corresponds to the similarly named HTTP method. The Java method annotated with this request method designator will process HTTP GET requests. The behavior of a resource is determined by the HTTP method to which the resource is responding. @POST The @POST annotation is a request method designator and corresponds to the similarly named HTTP method. The Java method annotated with this request method designator will process HTTP POST requests. The behavior of a resource is determined by the HTTP method to which the resource is responding. @PUT The @PUT annotation is a request method designator and corresponds to the similarly named HTTP method. The Java method annotated with this request method designator will process HTTP PUT requests. The behavior of a resource is determined by the HTTP method to which the resource is responding. @DELETE The @DELETE annotation is a request method designator and corresponds to the similarly named HTTP method. The Java method annotated with this request method designator will process HTTP DELETE requests. The behavior of a resource is determined by the HTTP method to which the resource is responding. @HEAD The @HEAD annotation is a request method designator and corresponds to the similarly named HTTP method. The Java method annotated with this request method designator will process HTTP HEAD requests. The behavior of a resource is determined by the HTTP method to which the resource is responding. @PathParam The @PathParam annotation is a type of parameter that you can extract for use in your resource class. URI path parameters are extracted from the request URI, and the parameter names correspond to the URI path template variable names specified in the @Path class‐level annotation. @QueryParam The @QueryParam annotation is a type of parameter that you can extract for use in your resource class. Query parameters are extracted from the request URI query parameters. The @Consumes annotation is used to specify the MIME media types of representations a resource can consume that were sent by the client. @Consumes @Produces @Provider http://docs.oracle.com/javaee/6/api/. The @Produces annotation is used to specify the MIME media types of representations a resource can produce and send back to the client: for example, "text/plain". The @Provider annotation is used for anything that is of interest to the JAX‐RS runtime, such as MessageBodyReader and MessageBodyWriter. For HTTP requests, the MessageBodyReader is used to map an HTTP request entity body to method parameters. On the response side, a return value is mapped to an HTTP response entity body by using a MessageBodyWriter. If the application needs to supply additional metadata, such as HTTP headers or a different status code, a method can return a Response that wraps the entity and that can be built using Response.ResponseBuilder. 37 Les restos … Basé sur le blog de Nicolas Martignole 38 Plus sur les ressources • Imaginons une application pour lister des restaurants par région, par type de cuisine, par évaluation des utilisateurs • Le 1741 à Strasbourg /alsace/bas-rhin/strasbourg/etoile/le1741 • Par extension tous les restaurants de Strasbourg /alsace/bas-rhin/strasbourg 39 Généralités sur l’implémentation • JAX‐RS fonctionnera en tant que servlet embarquée dans un conteneur léger. • Concernant les annotations, une ressource sera une classe avec, au moins, une annotation @Path présente sur l’une de ses méthodes ou sur la classe. • Par exemple une ressource qui représente des Restaurants : @Path("/restaurants") public class Restaurants { ... } 40 Généralités sur l’implémentation • Après compilation et déploiement dans un conteneur de Servlets comme Tomcat, la liste des restaurants sera donc accessible avec une url de ce type: http://monServeur:8080/rest/restaurants • Les annotations suivantes permettront de déclarer les méthodes de type REST: @GET, @POST, @PUT, @DELETE • L’annotation @Context permet de lire les en‐têtes HTTP 41 Généralités sur l’implémentation • Pour obtenir une uri /restaurants/chinois par exemple il faut ajouter méthode et qu’elle soit marquée avec un Path : @Path("/restaurants") public class Restaurants { @GET @Path("/chinois") public List getListOfChineseRestaurants() • Pour injecter des paramètres à une méthode, @Path("/restaurants") public class Restaurants { @Path("/{name}") public Restaurant getRestaurantByName( @PathParam("name") String restaurantName) { .... } 42 Généralités sur l’implémentation • Gestion des formats @Path("/restaurants") @Produces("text/html") public class Restaurants { @Path("/{name}") public Restaurant getRestaurantByName (@PathParam("name") String restaurantName) {...} @Path("/{name}/photo") @Produces("text/jpg") public String getPhotoForRestaurant (@PathParam("name") String restaurantName) {...} 43 Récapitulatif des annotations principales • Le serveur est en mode Consommateur ou Producteur en fonction de la méthode HTTP ! • En serveur (Producer) • Chemin vers la ressource : @Path("/..."), adossée à la classe • Chemin vers la ressource : @Path("/...{...}"), adossée à la méthode, avec d‘éventuels paramètres associes • Method HTTP GET : @GET, adossée à la méthode • Paramètre : @PathParam("..."), adossée au paramètre • En "client" pour le serveur (Consumer) • Chemin vers la ressource : @Path("/..."), adossée à la classe • Méthode HTTP POST : @POST, adossée à la méthode 44 Mise en œuvre 45 Développement d’un serveur REST • Avec JAX‐RS sur JBoss/WildFly : RESTEasy http://resteasy.jboss.org • Propose une gestion de projets par Maven https://maven.apache.org • Peut être utilisé dans n'importe quelle application J2EE • Intégration facilitée : détection automatique des services 46 Maven • Maven est un outil de construction de projets (build) open source. • Il permet de faciliter et d'automatiser certaines tâches de la gestion d'un projet Java. • automatiser certaines tâches : compilation, tests unitaires et déploiement des applications qui composent le projet • gérer des dépendances vis‐à‐vis des bibliothèques nécessaires au projet • générer des documentations concernant le projet • Intégration de tests unitaires • Tutoriel : Maven in 5 minutes https://maven.apache.org/guides/getting‐started/maven‐in‐five‐ minutes.html 47 Préparation • Créer un nouveau projet web Maven standard mvn archetype:generate -DgroupId=test -DartifactId=HelloWorldRest -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false • Le fichier pom.xml est le cœur de la configuration des projets Maven • Il faut y déclarer le dépôt public JBoss de Maven et la bibliothèque resteasy‐ jaxrs 48 L’arborescence d’un projet Maven 49 Configuration du fichier pom.xml 50 Un service REST simple 51 Configuration de l’application Des informations détaillées dans cette documentation http://docs.jboss.org/resteasy/ docs/2.2.1.GA/userguide/html/In stallation_Configuration.html 52 Compiler et déployer • mvn clean install • cp target/testID.war $WILDFLY_HOME/standalone/deployments 53 Un client • Nous réutilisons le client basique précédent 54 Une autre possibilité • Dans l’exemple précédent, nous avons déclaré le service REST avec l’écouter ResteasyBootstrap (voir le web.xml) • Une autre possibilité est de créer une classe qui étend javax.ws.rs.core.Application, et connecter notre service REST à la servlet RestEasy manuellement. 55 La classe de lien avec la servlet RestEasy 56 Nouvelle configuration 57 Un exemple un peu plus complexe Gestion des visiteurs d’une boutique 58 Implémentation du code du domaine • Dans une classe simple, un POJO, Visiteur, qui possède seulement un nom et un email • On va lui rajouter des annotations JAXB pour permettre une sérialisation/désérialisation transparente • Java Architecture for XML Binding (JAXB) http://www.oracle.com/technetwork/articles/java se/index-140168.html 59 Implémentation du code du domaine • On définit aussi un conteneur pour les listes de visiteurs, Visiteurs 60 Mise en œuvre du serveur • Le serveur va utiliser deux classes • La première fera le lien avec les méthodes HTTP • La deuxième fera le lien entre l’application et la servlet RestEasy • La première classe utilise les annotations REST • • • • • @Path : spécifie le pattern d’URL associé à la méthode @GET, @PUT, @DELETE, @POST : Spécifient la méthode HTTP utilisée @Consumes : Spécifie le format attendu en entrée @Produces : Spécifie le format attendu en sortie @PathParam : Spécifie un paramètre de l’URL 61 La classe de gestion des visiteurs 62 La classe de gestion des visiteurs 63 La classe de lien avec la servlet RestEasy 64 Quelques tests 65 Compléments 66 Gestion des exceptions • Rappel • Le protocole HTTP ne permet pas de remonter des exceptions ! • Solution • Le code Status HTTP peut être utilisé comme information • Architecture orientée Ressources favoriser la remontée de document pour une consultation par un client web 67 Exemple • Pour une classe TestExceptions.java 68 Arguments et valeurs en retour • Rappel : Le serveur est en mode Consommateur ou Producteur en fonction de la méthode HTTP! • Le passage par référence et donc les Callback ne sont pas supportés par les Services Web (et donc par les Services REST) • Arguments • GET : les arguments passés directement dans la requête • POST, PUT et DELETE : les arguments sont consommés par le serveur (annotation @Consumes) • Valeur en retour • GET/POST : une valeur en retour est attendue ; l'annotation @Produces précise le type MIME de la valeur en retour • Le code Status doit être utilisé 69 Bonnes pratiques • Privilégier l'utilisation de collections Ex : (GET) annuaire/Bob (GET) annuaire/personnes/Bob • Eviter les arguments explicites Ex : (GET) annuaire/personne/param=Bob (GET) annuaire/personnes/Bob • Eviter les noms de type « fonction » Ex : (POST) annuaire/renommer/Bob (POST) annuaire/personnes/Bob 70 Bonnes pratiques : le fichier WADL • Générer le fichier WADL pour notre serveur © M. Baron 71 Le fichier WADL • WADL (Web Application Description Language) est un langage de description XML de services de type REST • WADL est une spécification W3C initiée par SUN • www.w3.org/Submission/wadl • Description des services par éléments de type • Ressource, Méthode, Paramètre, Requête, Réponse • L’objectif est de pouvoir générer automatiquement les APIs clientes d’accès aux services REST • Remarques • Peu d’outils exploitent la description WADL (http://wadl.java.net) • Apparu bien plus tard 72 Génération du fichier WADL • Il faut indiquer explicitement à RestEasy de le faire 73 Génération du fichier WADL • Il faut indiquer explicitement à RestEasy de le faire 74 75 Conclusions • REST permet d’éviter la création de nombreuses servlets Java pour les actions des formulaires web ordinaires • La mise en œuvre dans JAX‐RS est quasiment transparente • Il faut toutefois faire attention à bien gérer l’idempotence des requêtes afin d’éviter les doublons ou les copies 76