Web des services : REST§
author: | Pierre-Antoine Champin |
---|---|
date: | 2011-2015 |
license: |
![]() |
author: | Pierre-Antoine Champin |
---|---|
date: | 2011-2015 |
license: |
![]() |
Ce support de cours est disponible à http://champin.net/enseignement/rest/.
Définition :
HTML y est donc remplacé par des formats de données, notamment XML ou JSON.
Cf. http://programmableweb.com/
code Javascript s'exécutant sur le navigateur
→ la distinction entre "site Web" et "service Web" s'estompe
Largement tiré du billet de blog de Martin Fowler.
On prend comme exemple un service de prise de rendez-vous avec des médecins.
On suppose que vous êtes en charge de développer:
L'API de votre service sera rendue publique, pour permettre le développement indépendant d'autres clients (applications mobiles, plugins pour des applications d'agenda, etc.).
POST /appointmentService HTTP/1.1
[various headers]
<openSlotRequest date="2010-01-04" doctor="mjones"/>
HTTP/1.1 200 OK
[various headers]
<openSlotList>
<slot doctor="mjones" start="1400" end="1450" />
<slot doctor="mjones" start="1600" end="1650" />
</openSlotList>
Note
Le choix de XML n'est pas déterminant ici ; on aurait pu choisir un autre format (JSON, YAML...).
POST /appointmentService HTTP/1.1
[various headers]
<appointmentRequest>
<slot doctor="mjones" start="1400" end="1450"/>
<patient id="jsmith"/>
</appointmentRequest>
HTTP/1.1 200 OK
[various headers]
<appointment>
<slot doctor="mjones" start="1400" end="1450"/>
<patient id="jsmith"/>
</appointment>
HTTP/1.1 200 OK
[various headers]
<appointmentRequestFailure>
<slot doctor="mjones" start="1400" end="1450"/>
<patient id="jsmith"/>
<reason>Slot not available</reason>
</appointmentRequestFailure>
Principe : exposer au client les ressources qui constituent le service (via différentes URLs).
POST /appSvc/doctors/mjones HTTP/1.1
[various headers]
<openSlotRequest date="2010-01-04"/>
HTTP/1.1 200 OK
[various headers]
<openSlotList>
<slot id="1234" doctor="mjones" start="1400" end="1450"/>
<slot id="5678" doctor="mjones" start="1600" end="1650"/>
</openSlotList>
Note
Le contenu des messages est simplifié,
car la ressource donne un contexte (ici : doctor="mjones"
)
POST /appSvc/slots/1234 HTTP/1.1
[various headers]
<appointmentRequest>
<patient id="jsmith"/>
</appointmentRequest>
HTTP/1.1 200 OK
[various headers]
<appointment>
<slot id="1234" doctor="mjones" start="1400" end="1450"/>
<patient id="jsmith"/>
</appointment>
En théorie, les différentes URLs peuvent être construites de n'importe quelle manière. Par exemple :
appSvc/doctor/mjones |
appSvc/slot/1234 |
appSvc?doctor=mjones |
appSvc?slot=1234 |
appSvc/7c277937e450 |
appSvc/d75bdf681d78 |
... | ... |
En pratique,
Principe : expliciter la sémantique de l'API via la sémantique de HTTP
GET /appSvc/doctors/mjones/slots?date=20100104&status=open HTTP/1.1
Host: royalhope.nhs.uk
HTTP/1.1 200 OK
[various headers]
<openSlotList>
<slot id="1234" doctor="mjones" start="1400" end="1450"/>
<slot id="5678" doctor="mjones" start="1600" end="1650"/>
</openSlotList>
POST /appSvc/slots/1234 HTTP/1.1
[various headers]
<appointmentRequest>
<patient id="jsmith"/>
</appointmentRequest>
HTTP/1.1 201 Created
Location: http://royalhope.nhs.uk/slots/1234/appointment
[various other headers]
<appointment>
<slot id="1234" doctor="mjones" start="1400" end="1450"/>
<patient id="jsmith"/>
</appointment>
HTTP/1.1 409 Conflict
[various headers]
<openSlotList>
<slot id="5678" doctor="mjones" start="1600" end="1650"/>
</openSlotList>
Note
Un exemple d'utilisation de la sémantique des code de status HTTP est le comportement des navigateurs lorsqu'ils reçoivent un code 401 (Unauthorized) : au lieu de reporter l'erreur directement, ils réclament à l'utilisateur un login et un mot de passe.
Principe : permettre au client de découvrir les actions possibles, plutôt que d'avoir à les connaître à l'avance.
GET /doctors/mjones/slots?date=20100104&status=open HTTP/1.1
Host: royalhope.nhs.uk
HTTP/1.1 200 OK
[various headers]
<openSlotList>
<slot id="1234" doctor="mjones" start="1400" end="1450">
<book href="/appSvc/slots/1234"/>
</slot>
<slot id="5678" doctor="mjones" start="1600" end="1650">
<book href="/appSvc/slots/5678"/>
</slot>
</openSlotList>
HTTP/1.1 201 Created
Location: http://royalhope.nhs.uk/slots/1234/appointment
[various headers]
<appointment uri="/slots/1234/appointment">
<slot id="1234" doctor="mjones" start="1400" end="1450"/>
<patient id="jsmith"/>
<cancel href="/appSvc/slots/1234/appointment"/>
<addTest href="/appSvc/slots/1234/appointment/tests"/>
<changeTime
href="/appSvc/doctors/mjones/slots?date=20100104&status=open"/>
<updateContactInfo href="/patients/jsmith/contactInfo"/>
<help href="http://appSvc.com/help/appointment"/>
</appointment>
« REST emphasizes
- scalability of component interactions,
- generality of interfaces,
- independent deployment of components, and
- intermediary components to
- reduce interaction latency,
- enforce security, and
- encapsulate legacy systems. »
(Roy Fielding)
Problème de performance
La dimension et l'expansion constante du Web obligent à considérer dès le départ les problèmes d'échelle.
Problème de robustesse
Le système ne peut pas être 100% opérationnel 100% du temps.
Facilite le développement des composants
Réutilisation de bibliothèques standard, interopérabilité.
Évolutivité
Web de documents, Web de services, Web 2.0, Web des données, Web sémantique...
Principle of partial understanding (Michael Hausenblas)
Contrainte d'échelle
Pas de centralisation possible sur le Web.
Adoption et évolution rapides
Grassroot movement (poussé par le bas), « sélection naturelle », modèle du Bazar (Eric Raymond)
Réduire la latence
Assurer la sécurité
Encapsulant des services
Contraintes de REST, d'après Fielding :
NB: la description qui en suit doit beaucoup à Miguel Grinberg.
Separation of concern (Edsger W. Dikstra)
Remarques :
Note
Fournit "gratuitement" la possibilité d'avoir plusieurs clients.
Note
Les verbes et les statuts pré-définis par HTTP ont une sémantique suffisamment précise pour informer les caches de la possibilité de « cacher » ou non un résultat.
NB: l'utilisation systématique de POST empêche l'exploitation des caches.
HTTP permet de contrôler plus finement le cache avec un certain nombres de champs d'en-tête
(Cache-Control
, Expires
).
Le serveur ne doit pas s'encombrer du contexte de l'interaction. Ce contexte est rappelé à chaque requête par le client, et les modifications de contexte sont indiquées dans la réponse.
→ auto-suffisance des messages.
Inconvénients
Avantages
Note
La plupart des framework de développement Web offrent des fonctionalités qui gèrent les sessions de manière quasiment transparente pour le développeur. Attention cependant à avoir conscience des avantages et des inconvénients.
Une ressource n'est manipulée par le client qu'à travers des représentations de son état.
![]() Tableau de René Magritte - Source Wikipedia |
|
http://www.google.fr/search?q=hypertexte
Le web des services n'est pas différent du web des documents : un agent (par exemple le navigateur) interagit avec des serveurs pour le compte d'un utilisateur.
La différence réside dans le degré d'autonomie de cet agent : différence de degré mais pas de nature.
Sémantique déclarative plutôt qu'opérationnelle
Une des évolutions majeures apportée par UNIX au domaine des systèmes d'exploitations a été l'unification de la notion de fichier :
open
, read
, write
...)pour manipuler des ressources aussi variées que des fichiers de données, des périphériques, des sockets...
→ le succès de cette unification donne un certain crédit à l'unification proposée par REST.
Contrairement à SOAP, REST ne dispose pas d'un langage standard pour la description formelle des interfaces des services.
Un tel langage offrirait pourtant des fonctionalités intéressantes :
Il y a eu de nombreuses propositions dans ce sens :
Mais aucune ne s'est encore imposée...
SOAP : Simple Object Access Protocol
Pourtant, SOAP recontre une certaine résistance
Une spécification volumineuse
SOAP est parfois perçu comme limitant paradoxalement l'interopérabilité des services Web.
Le succès du Web doit beaucoup à sa simplicité de mise en œuvre, simplicité qui fait défaut à SOAP.
Avec SOAP, le prototole HTTP est utilisé comme un simple protocole de transport.
→ SOAP se prive d'une grande partie des mécanismes du Web
L'« implémentation de référence » de REST.
REST → HTTP mais
HTTP → REST
Requête à http://www.w3.org/
GET / HTTP/1.1
Host: www.w3.org
User-Agent: Mozilla/5.0 (X11; U; Linux i686;
fr; rv:1.9.1) Gecko/20090624 Firefox/3.5
Accept: text/html,application/xhtml+xml,
application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: UTF-8,*
Connection: keep-alive
Keep-Alive: 300
Réponse de http://www.w3.org/
HTTP/1.x 200 OK
Date: Mon, 02 Nov 2009 22:46:26 GMT
Server: Apache/2
Accept-Ranges: bytes
Content-Type: text/html; charset=utf-8
Content-Length: 29794
Etag: "7462-477341dcfb940;89-3f26bd17a2f00"
Last-Modified: Sat, 31 Oct 2009 05:07:09 GMT
Content-Location: Home.html
Vary: negotiate,accept
Cache-Control: max-age=600
Expires: Mon, 02 Nov 2009 22:56:26 GMT
Connection: close
(data) ...
La requête consiste à appliquer un verbe à la ressource.
Host
est obligatoire depuis HTTP/1.1 (car un même serveur peut
servir plusieurs noms de domaine).GET / HTTP/1.1
Host: www.w3.org
La réponse commence par un code de statut numérique indiquant le résultat .
HTTP/1.x 200 OK
HTTP définit quatre (principaux) verbes pour la manipulation des ressources :
Les requêtes POST et PUT supposent un envoi de données (payload) au serveur. Ces données peuvent être de n'importe quel type, qui sera spécifié dans la requête (Content-Type
).
Certains auteurs préfèrent caractériser les verbes HTTP simplement par rapport à leurs propriétés :
qui conditionnent le comportement des composants intermédiaires.
HTTP définit 40 codes de statut, répartis en cinq catérogires :
Catégories | Exemples |
---|---|
1xx : Information | 100 Continue |
2xx : Succès | 200 OK |
3xx : Redirection | 301 Moved Permanently |
4xx : Erreur client | 404 Not Found, 401 Unauthorized |
5xx : Erreur serveur | 500 Internal Server Error |
Le client et le serveur donnent des indications sur leur identité et leur contexte.
User-Agent: Mozilla/5.0 (X11; U; Linux i686;
fr; rv:1.9.1) Gecko/20090624 Firefox/3.5
Server: Apache/2
Date: Mon, 02 Nov 2009 22:46:26 GMT
Le client annonce les types de contenus qu'il est capable d'accepter.
Accept: text/html,application/xhtml+xml,
application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: UTF-8,*
Content-Type: text/html; charset=utf-8
Content-Location: Home.html
Vary: negotiate,accept
En-tête Alternates de http://www.w3.org/
Alternates: {"Home.html" 1 {type text/html} {charset utf-8} {length 29813}},
{"Home.xhtml" 0.99 {type application/xhtml+xml} {charset utf-8} {length 29813}}
Le serveur fournit des méta-données relatives à la représentation.
Etag: "7462-477341dcfb940;89-3f26bd17a2f00"
Last-Modified: Sat, 31 Oct 2009 05:07:09 GMT
Ces méta-données font partie de l'état du client, et sont donc censées être fournie par lui lors de requêtes ultérieures (statelessness).
If-None-Match: "7462-477341dcfb940;89-3f26bd17a2f00"
If-Modified-Since: Sat, 31 Oct 2009 05:07:09 GMT
Si la ressource n'a pas été modifiée, le serveur répondra par un statut 304 Not Modified et une réponse vide → économie.
D'autres méta-données concernent la « cachabilité » de la représentation.
Cache-Control: max-age=600
Expires: Mon, 02 Nov 2009 22:56:26 GMT
Cache-Control
(introduit dans HTTP 1.1) offre plus d'expressivité que Expires
(private
, no-transform
...).
Cache-Control
peut également être utilisé dans une requête, par exemple :
Cache-Control: no-cache
HTTP étant un protocole sans état, chaque requête peut être envoyée sur une nouvelle connexion TCP (ce qui était imposé par HTTP 1.0).
Pour des raisons d'optimisation, le client et le serveur peuvent spécifier qu'ils souhaitent / acceptent de garder la connexion ouverte pour des requêtes ultérieures. Ceci est fait explicitement pour conserver l'auto-suffisance des requêtes.
Connection: keep-alive
Keep-Alive: 300
Connection: close