Architectures Web Services RESTful
Inria Bordeaux – Sud-Ouest
France
ENSEIRB PG306
REST
●
REST – Representational State Transfer
– Roy Fielding (2000)
– Décollage vers 2006-2007
– Alternative à SOAP – protocole historique des Web Services
– Désormais l'interface prédominante dans les WS
●
Approche minimaliste
A. Denis – ENSEIRB PG306 -2
RESTful
●
Vrai REST / faux REST
●
REST est une philosophie de conception d'interface
– Pas réellement une norme
– Pas un protocole
●
RESTful = vrai REST
– Parfois : architecture REST, service RESTful
●
A. Denis – ENSEIRB PG306 -3
Propriétés REST
●
Client/serveur
●
Sans état – serveur sans mémoire
●
Cacheable, proxy
– Conséquence de « sans état »
●
Interface uniforme
– Ressources identifiées de façon unitaire
– Manipulation des ressources au travers de représentations
– Messages auto-descriptifs
– HATEOS – Hypermedia as the Engine of Application State
●
Système en couches
A. Denis – ENSEIRB PG306 -4
Ressources REST
●
Architecture centrée sur les ressources
– Pas sur les actions
●
Entité de base : une ressource
– ~ objet
– Arboressence de ressources
●
Point d'entrée de l'application : ressource racine
– Verbes (~méthodes) appliqué aux ressources
●
Façon base de données: put, get, create, delete
– Liens direct entre ressources
A. Denis – ENSEIRB PG306 -5
HATEOS
Hypermedia as the Engine
●
RPC en HTTP en non au-dessus de HTTP
●
Pourquoi ré-implémenter un mécanisme RPC (SOAP) sur HTTP, alors que
HTTP fournit déjà nativement :
– Un système de requêtes (GET, POST, PUT, CREATE, DELETE)
– Un système d'adressage d'entités (URI)
– Un système de retour d'erreur (404, etc.)
– Un système de typage (Content-Type, etc.)
●
HTTP est conçu depuis l'origine comme un vrai protocole de requêtes
– Même si le WWW utilise quasi-exclusivement GET
A. Denis – ENSEIRB PG306 -6
Représentations
●
Les données échangées sur le fil sont une représentation
– Clairement distincte de l'implémentation
– Sérialisées en un format à la carte
●
Souvent JSON et XML
●
Personnalisable par le client
– Headers HTTP Accept et Content-Type
●
Représentation auto-descriptive
– Content-Type, charset, compression
– Tout est déjà prévu dans HTTP
A. Denis – ENSEIRB PG306 -7
Représentations - Exemples
●
Représente une ressource complète
– S'il y a besoin de découper, c'est que le modèle de données est à revoir
●
Représentation JSON et XML, pour une même donnée
– Applications Web/AJAX
souvent en JSON {
"ID": "1",
"Name": "M Vaqqas",
– XML : habituel en WS "Email": "[email protected]",
"Country": "India"
– D'autres formats sont }
possibles
<Person>
<ID>1</ID>
<Name>M Vaqqas</Name>
<Email>[email protected]</Email>
<Country>India</Country>
</Person>
Exemple : Dr. Dobbs, M. Vaqqas
A. Denis – ENSEIRB PG306 -8
Messages
●
Format habituel des messages HTTP
●
Les entités HTTP sont mappées directement sur les entités REST :
– Les requêtes HTTP sur les verbes REST
– Les URI HTTP sur les ressources REST
A. Denis – ENSEIRB PG306 -9
Requête - exemple
POST http://MyService/Person/
Host: MyService
Content-Type: text/xml; charset=utf-8
●
Exemple de requête POST Content-Length: 123
<?xml version="1.0" encoding="utf-8"?>
<Person>
<ID>1</ID>
<Name>M Vaqqas</Name>
<Email>
[email protected]</Email>
<Country>India</Country>
</Person>
●
PUT v.s. POST – par convention :
– PUT : crée/actualise une ressource en donnant l'URI de la ressource
– POST : on donne l'URI d'une méthode
●
C'est le serveur qui assigne l'URI de la ressource
A. Denis – ENSEIRB PG306 - 10
Bonne conduite
●
A l'utilisateur d'appliquer les conventions
●
Si on peut utiliser une URI de ressource, c'est que c'est une ressource !
– À ne pas faire : GET http://MyService/Persons?id=1
– Préférer : GET http://MyService/Persons/1
●
GET ne fait pas d'effet de bord
– À ne pas faire : GET http://MyService/DeletePerson/1
– Préférer : DELETE http://MyService/Persons/1
●
PUT est idempotent
– Appeler la requête plusieurs fois à le même effet qu'une seule fois
●
Pas d'état dans le serveur
– À ne pas faire : GET http://MyService/Persons/1 HTTP/1.1
GET http://MyService/NextPerson HTTP/1.1
– Préférer : liste de liens, itérateur côté client
A. Denis – ENSEIRB PG306 - 11
Description d'interfaces
<method name="GET" id="ItemSearch">
<request>
<param name="Service" style="query"
fixed="AWSECommerceService"/>
<param name="Version" style="query"
●
Description d'une interface REST fixed="2005-07-26"/>
<param name="Operation" style="query"
– WSDL 2.0 a une projection REST fixed="ItemSearch"/>
<param name="SubscriptionId" style="query"
type="xsd:string" required="true"/>
– WADL - Web Application Description <param name="SearchIndex" style="query"
type="aws:SearchIndexType"
Language required="true">
<option value="Books"/>
<option value="DVD"/>
●
Décrit les types <option value="Music"/>
</param>
– RSDL - RESTful Service Description <param name="Keywords" style="query"
type="aws:KeywordList" required="true"/>
Language <param name="ResponseGroup" style="query"
type="aws:ResponseGroupType"
repeating="true">
●
Décrit les URI <option value="Small"/>
<option value="Medium"/>
<option value="Large"/>
●
Langages d'usage marginal <option value="Images"/>
</param>
</request>
●
Le plus souvent, doc en texte <response>
<representation mediaType="text/xml"
element="aws:ItemSearchResponse"/>
</response>
</method> Exemple : Amazon
A. Denis – ENSEIRB PG306 - 12
Outils pour services RESTful
●
Assemblage de protocoles et formats normalisés
– Pas de modèle de programmation spécifique !
– Pas d'outil / API / workflow standard
– Outil dédié ou assemblage ad-hoc d'une lib HTTP et d'une lib JSON
●
Approches asymétriques côté client et serveur - typiquement :
– Serveur : framework, annotations, serveurs d'applications
– Client : scripts, langages web, assemblage ad-hoc HTTP+parseur
JSON/XML
A. Denis – ENSEIRB PG306 - 13
Middleware pour service RESTful
●
JAX-RS - Java API for RESTful Web Services
– Annotations de code Java
●
Frameworks Java
– Restlet
●
Framework Java, pionnier (2007), interface spécifique et JAX-RS
– Apache CXF
●
Fondation Apache, WS-*, RESTful spécifique ou JAX-RS, etc.
– Oracle Jersey
●
JAX-RS, Maven, Tomcat
– Oracle WebLogic, RedHat JBoss RESTEasy, Java JSP
●
Ruby-on-rails, Python Django
●
Solutions ad-hoc
– Servlets ad-hoc, php+rewrite rule, Node.js, etc.
A. Denis – ENSEIRB PG306 - 14
Clients REST
●
Grand nombre d'approches !
– Tout ce qui sait faire du HTTP peut être client REST
●
Partie cliente d'un framework REST
●
Bibliothèques Ruby, python
●
Assemblage ad-hoc en Javascript, PHP
●
En C : libcurl + Jansson, libcurl + expat
●
Script shell, curl
A. Denis – ENSEIRB PG306 - 15
JAX-RS
●
JAX-RS - Java API for RESTful Web Services
– Annotations de code Java
– Pour préciser : type de requête, URI, type
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/hello")
public class Hello
{
@GET
@Produces(MediaType.TEXT_PLAIN)
public String sayPlainTextHello()
{
return "Hello Jersey";
}
}
Exemple : Jersey
A. Denis – ENSEIRB PG306 - 16
JAX-RS
@Path("/hello")
public
●
class Hello
{
// This method is called if TEXT_PLAIN is request
@GET
●
@Produces(MediaType.TEXT_PLAIN)
public String sayPlainTextHello() {
return "Hello Jersey";
}
// This method is called if XML is request
@GET
@Produces(MediaType.TEXT_XML)
public String sayXMLHello() {
return "<?xml version=\"1.0\"?>" + "<hello> Hello Jersey" + "</hello>";
}
// This method is called if HTML is request
@GET
@Produces(MediaType.TEXT_HTML)
public String sayHtmlHello() {
return "<html> " + "<title>" + "Hello Jersey" + "</title>"
+ "<body><h1>" + "Hello Jersey" + "</body></h1>" + "</html> ";
}
}
Exemple : Jersey
A. Denis – ENSEIRB PG306 - 17
Référence JAX-RS
●
Liste des annotations
@Path indique un morceau du chemin de l'URI
@GET désigne une méthode pour traiter les requêtes GET
@PUT désigne une méthode pour traiter les requêtes PUT
@POST désigne une méthode pour traiter les requêtes POST
@DELETE désigne une méthode pour traiter les requêtes DELETE
@HEAD désigne une méthode pour traiter les requêtes HEAD
@PathParam extrait un paramètre du chemin
@QueryParam extrait un paramètre de l'URI
@Consumes type MIME des données acceptées par la méthode
@Produces type MIME des données produites par la méthode
@Provider indique qu'une classe fournit des méthodes auxiliaires pour JAX-RS
A. Denis – ENSEIRB PG306 - 18
JAXB
●
JAXB - Java Architecture for XML Binding
– Sérialiseur/parseur XML en Java
– Entièrement généré par annotations de code
– Conversion XSD <-> code Java annoté
import javax.xml.bind.annotation.*;
@XmlRootElement(name="hello")
public class HelloObject
{
public HelloObject(int a)
{
id = a;
}
@XmlElement(name="id")
int id;
}
A. Denis – ENSEIRB PG306 - 19
Travail à faire
- 20
Exemple REST
●
Téléchargez l'exemple hello-jaxrs.tar.gz sur la page du cours
●
Les exemples utilisent :
– L'interface JAX-RS de Restlet côté serveur
– Un assemblage ad-hoc Apache Http Components + JAXB côté client
– Des routines de test à l'aide de curl
– Vous êtes encouragés à tester d'autres solutions côté client selon les
langages que vous maîtrisez (Ruby, Python, PHP, Javascript)
●
du moment qu'une bibliothèque http cliente est disponible et un parseur XML
ou JSON
A. Denis – ENSEIRB PG306 - 21
REST avec curl
●
Parcourez le code du serveur
– Identifiez les différents types de requêtes
– Identifiez les manipulations et conversions de données (texte, XML)
●
Lancez des requêtes vers le serveur à l'aide de l'outil curl
– Consultez le manuel de curl si besoin
●
Note : REST utilise intensivement le Content-Type. Précisez-le
toujours à curl
●
Testez les différents types de requêtes : GET, PUT, POST
A. Denis – ENSEIRB PG306 - 22
REST avec le client Java Http Components
●
Parcourez le code du client
– Identifiez les parties relatives à HTTP et à XML
●
Ajoutez d'autres requêtes vers les ressources du serveur
A. Denis – ENSEIRB PG306 - 23
Construire un service REST
●
Nous proposons d'écrire un service à la IMDb
●
Proposez une interface pour décrire un film avec : titre, réalisateur, acteurs
– Quelles sont les différentes ressources ?
– Comment construire l'arboressence ?
– Quelles sont les opérations ?
●
Il faut au moins : ajout d'entrée, interrogation d'une fiche, recherche
par titre, recherche par personne (réalisateur, acteur)
●
Créez un script shell utilisant curl pour remplir la base à l'initialisation
●
Créez un client Java effectuant des recherches
A. Denis – ENSEIRB PG306 - 24
Vers un service externe
●
Un grand nombre de sites « Web 2.0 » proposent une interface REST :
Facebook, Google, Twitter, Instagram, IMDb, Wikipedia, etc.
●
Choisissez votre site favori, consultez sa documentation, écrivez un client !
– Note : il y a toujours une authentification qui peut être délicate à gérer
A. Denis – ENSEIRB PG306 - 25
À vous de jouer !
http://dept-info.labri.fr/~denis/