REST
Un Survol des principaux concepts
1
REST?
• REST (REpresentational State Transfer) est un style
d’architecture pour les systèmes hypermédia distribués
• REST n’est pas un protocole (tel que HTTP) ou un format
• Style d'architecture particulièrement bien adapté au WWW mais
n'est pas dépendant du Web.
– Peut s'appliquer à d'autres protocoles d'application que HTTP.
2
REpresentational State Transfer(REST)
• L’URL c’est la Ressource
• GET pour afficher la page à partir du serveur
– Transfert de l’état de la ressource sur le navigateur du client
• Les ressources sont accessibles à travers des liens hyperlink
3
Concepts clés
• Ressources (noms)
– Identifiées par une URI, Exemple: [Link]
• Méthodes (verbes) afin de manipuler les ressources
– Create, Read, Update, Delete
• Représentation est la manière de voir/échanger l’état de
la ressource
– Transfert de données et d’état entre le serveur et le client
– XML, HTML, JSON...
4
Exemple
5
REST en 5 étapes
• Donner un ID pour chaque ressource
• Utiliser les méthodes standards d’HTTP
• Lier les ressources entre elles
• Choix entre multiples représentations
• Communication sans état (Stateless)
6
Etape 1: Donner un ID pour chaqueressource
• [Link]
o Le client num 1234 de la collection de clients
• [Link]
o Le produit num 4554 de la collection de produits
• [Link]
o La commande num 12 du client num 1234
7
Etape 2: Utiliser les méthodes standardsd’HTTP
• GET: Lecture d’une information (ressource)
– éventuellement déjà présente dans le cache
– Sans effet de bord
o Exp: GET /toto/customers/1234
• POST: Créer une nouvelle information (ressource) sans l’ID
– Créer la ressource et la rajouter à une collection
o Exp: POST /toto/customers
• Ajoute le client spécifié dans le POSTDATA à la collection des clients.
• L’opération retourne l’URI de la nouvelle ressource créée
8
Etape 2: Utiliser les méthodes standardsd’HTTP
• PUT: Mise à jour /création d’une ressource avec un ID
connu
o Exp: PUT /toto/customers/1234
• Remplace le client num 1234 avec une nouvelle version
• DELETE: Effacer une ressource
o Exp: DELETE /toto/customers/1234
• Efface le client num 1234 du système
9
Etape 3: Lier les ressources entreelles
• Permet au client de faire évoluer l’application d’un état à un autre
en suivant des liens et en remplissant des formulaires
<order self=’[Link]
<amount>23</amount>
<product ref=’[Link] />
<customer ref=’[Link] />
</order>
10
Etape 4: Choix entre multiples représentations
• Plusieurs formats possibles selon les besoins
– XML, JSON, (x)HTML
// 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 isrequest
@GET
@Produces(MediaType.TEXT_HTML)
public String sayHtmlHello() {
return "<html> " + "<title>" + "Hello Jersey" + "</title>" + "<body><h1>" +
"Hello Jersey" + "</body></h1>" + "</html> ";
}
11
Etape 5: Communication sans état(Stateless)
• HTTP est Stateless (sans état)
• Tout ce qui est nécessaire pour traiter une demande est
dans l’objet Request
• Le client est responsable de l’état de l’application
• Le serveur est responsable de l’état de la ressource
• Exp: Agence de voyage en ligne
– Créer un voyage, définir l’itinéraire, le soumettre, etc.
– Le tout est géré coté client et non pas sur la session du serveur
12
Etape 5: Communication sans état(Stateless)
13
REST: Principaux avantages
• Coté Serveur
– Plus de passage à l’échelle (scalable)
– Reprise après panne
– Utilisation optimisée du cache
– Couplage réduit
– Fonctionne avec les infrastructures actuelles
– Interface uniforme
• Coté Client
– Liens bookmarkables (favoris)
– Besoin d’un simple navigateur
– Plusieurs langages supportés
– Plusieurs choix de formats de données
14
REST
Utilisation d’annotations JAX-RS
15
Etape 1: Donner un ID pour chaqueressource
• Une ressource => Classe POJO (Plain Old Java Object)
– Pas d’interface requise!
• L’ID est défini par l’annotation @Path
– Relative au contexte de déploiement
– Peut être utilisée pour annoter la classe ou directement la
méthode censée retourner la ressource
16
Etape 1: Donner un ID pour chaqueressource
• Comment mapper les URIs aux Classes:
17
Etape 1: Donner un ID pour chaqueressource
• Deux manières de créer des sous-ressources
public class ItemResource {
@Path("/items/{id}/")
@GET
public ItemConveter get(@PathParam("id") Long id) {
.....
}
@Path("/items/")
public class ItemsResource {
@Path("{id}/")
public ItemResource getItemResource(@PathParam("id") Long id) {
...
return resource;
}
18
Etape 2: Utiliser les méthodes standardsd’HTTP
• Annoter les classes de ressources avec les méthodes standards selon
le besoin
– @GET, @PUT, @POST, @DELETE
Le @Path n’est pas
donné dans cet exemple,
il est défini avant la
signature de la classe
19
Etape 2: Utiliser les méthodes standardsd’HTTP
• Possibilité d’extraire les informations à partir des
paramètres de la requête avec @QueryParam
20
Etape 3: Lier les ressources entre elles
• UriInfo donne l’information sur le contexte de déploiement,
l’URI, et le chemin jusqu’à la ressource
• UriBuilder offre des facilités pour créer les URIs des
ressources
21
Etape 4: Choix entre multiples représentations
• Annoter les méthodes ou bien les classes avec
– @ProduceMime, @ConsumeMime
22
Etape 4: Choix entre multiplesreprésentations
23
Etape 5: Communication sans état(Stateless)
• Une nouvelle instance est créée pour chaque requête
– Réduit les problèmes de concurences
• Les sessions HTTP ne sont pas supportées
• Le développeur doit gérer l’état de l’application à
travers les représentations
24
REST …
• Style architectural de plus en plus utilisé
• Défini comme étant le vrai WEB contrairement aux WS
SOAP
• Eviter de généraliser!! Le tout REST ou le tout SOAP!!
25
Zoom sur JAX-RS 2.0
• JAX-RS is a framework that helps you in writing the
RESTful web services on the client side as well as on
the server side.
• Jersey is the reference implementation of the JAX-
RS. Along with the enhancements in Java EE.
26
Le [Link]
...........
<servlet>
<servlet-name>simpleJerseyExample</servlet-name>
<servletclass>
[Link]</servletclass>
<init-param>
<param-name>[Link]</paramname>
<param-value>[Link]</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>simpleJerseyExample</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
...........
27
Le HelloWorld
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
/**
* helloWorld Root Resource
*/
@Path("helloWorld")
public class HelloWorldResource{
@GET
@PRODUCES(MediaType.TEXT_PLAIN)
public String greet(){
return "Hello World!!!";
}
}
Pour tester? => sur votre navigateur, ou Chrome postman, ou SoapUI ou curl, etc.
[Link]
28
Les annotations
• @Path("resource_path"): Indique le path pour accéder à la ressource.
Il est relatif à l’URL :
@serveur/nomApplication/urlPattern dans le [Link]/ [@Path("resource_path")]*
•@PathParam: utilisé pour injecter des valeurs à partir de l’URL vers les paramètres
de la méthode
• @GET
• @PUT
• @POST
• @DELETE
• @Produces(MediaType.TEXT_PLAIN): définit le type MIME renvoyé par la méthode
annotée par les méthodes HTTP (CRUD)
• @Consumes(type):définit quel type MIME est consommé par la méthode
29
Les annotations
• @PathParam
• @QueryParam
• @MatrixParam
• @FormParam
• @BeanParam
• @DefaultValue
• @HeaderParam
• @CookieParam
• @Context
30
@Path
@Path("helloWorld")
public class HelloWorldResource {
@GET
@Produces("text/plain")
public String sayHello() {
return "Hello World!";
}
}
Des variables peuvent se rajouter à l’URI
• au niveau de la classe :
@Path("/helloWorld/{name}")
public class HelloWorldResource {
@GET
@Produces("text/plain")
public String sayHello(@PathParam("name") String name) {
return "Hello, " + name; • au niveau de la méthode:
} @Path("/helloWorld")
} public class HelloWorldResource {
@GET
@Produces("text/plain")
@Path("{name}")
public String sayHello(@PathParam("name") String name) {
return "Hello, " + name;
}
}
31
GET [Link]
@Path avec Expression Régulière
@Path("/helloWorld")
public class HelloWorldResource {
@GET
@Produces("text/plain")
@Path("{name: ([a-zA-Z])*}")
public String sayHello(@PathParam("name") String name) {
return "Hello, " + name;
}
}
•Ok :
[Link]
Output:
Hello, CCDAD
•Erreur:
[Link]
Output:
HTTP Status 404, Not Found
32
Les opérations HTTP
• @GET: Lire une représentation d’une ressource. Aucun effet de
bord
• @PUT: Utilisée pour l’update. Peut être utilisée pour la création si
l’id de la ressource est défini par le client au lieu du Serveur
• @DELETE: pour supprimer une ressource
@DELETE
@Path("{name}")
public void
delete(@PathParam("name")String name)
{
[Link]("DELETE: " + name);
}
33
Les opérations HTTP
• @POST: pour la création d’une nouvelle ressource
@POST
@Produces(MediaType.TEXT_HTML)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public void newTodo(@FormParam("id") String i d ,
@FormParam("summary") S t r i n g summary,
@FormParam("description") S t r i n g d e s c r i p t i o n ,
@Context HttpServletResponse servletResponse) throws IOException {
Todo todo = new Todo(id,summary);
i f (description!=null){
[Link](description);
}
[Link]().put(id, todo);
servletResponse .sendRedirect("../[Link]");
}
34
@Produces & @Consumes
• Peut être fixée au niveau de la classe et redéfini au niveau de la méthode
• Peut prendre plusieurs types à la fois
@Path("/helloWorld") @GET
@Produces("text/plain") @Produces({"application/xml", "application/json"})
public class HelloWorldResource { public String greet() {
@GET ...
public String greet() { }
...
}
@GET
@Produces("text/html")
public String greetUser() {
...
}
}
35
Les annotations pour lesparamètres
@PathParam
@GET
@Path("{name}")
public String getUserByName(@PathParam("name") String name) {
return name;
}
@QueryParam
@Path("/userService")
public class UserResource {
... URI Pattern: /services/userService/queryParam?name=Abdallah
@GET
@Path("/queryParam")
public String getUser(@QueryParam("name") String name) {
[Link]("Name: " +name);
return name;
}
...
} 36
@DefaultValue
@GET
@Path("/queryParam")
public String getUser (
@QueryParam("name")String name,
@DefaultValue("15") @QueryParam("age") String age) {
[Link]("Name: " + name);
[Link]("Age: " + age);
return name;
}
URI Pattern:
/services/userService/queryParam?name=Abdallah
URI Pattern:
/services/userService/queryParam?name=Abdallah&age=20
37
@MatrixParam
Exemple URI Pattern: /service/getUserById/1;name=Abdallah;age=10
@GET
@Path("/getUserById/{userId}")
public Response getUserById(
@PathParam("userId") String userId,
@MatrixParam("name") String name,
@DefaultValue("15") @MatrixParam("age") String age) { return
Response
.status(200)
.entity("Id: " + userId + ", Name: " + name + ", Age: " + age)
.build();
}
38
@FormParam
<FORM action="" method="post">
ID: <INPUT type="text" name="id"><BR>
summary : <INPUT type="text" name="summary"><BR>
description: <INPUT type="text" name="description"><BR>
@POST <INPUT type="submit" value="Send">
</FORM>
@Produces(MediaType.TEXT_HTML)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public void newTodo(@FormParam("id") String i d ,
@FormParam("summary") S t r i n g summary,
@FormParam("description") S t r i n g d e s c r i p t i o n ,
@Context HttpServletResponse servletResponse) throws IOException {
Todo todo = new Todo(id,summary);
i f (description!=null){
[Link](description);
}
[Link]().put(id, todo);
[Link]("../[Link]");
}
39