Web des services : REST§

author:Pierre-Antoine Champin
date:2011-2015
license: Creative Commons License

Introduction§

Service Web§

Définition :

  • Application Web, coté serveur,
  • destinée à être utilisée par des programmes,
  • et non par des utilisateurs (à travers un navigateur).

HTML y est donc remplacé par des formats de données, notamment XML ou JSON.

Cf. http://programmableweb.com/

Applications clientes§

  • applications de bureau
  • applications mobiles
  • autres services Web
  • code Javascript s’exécutant sur le navigateur

    → la distinction entre “site Web” et “service Web” s’estompe

REST§

  • Representational State Transfer
  • Un style architectural
  • Un ensemble de bonne pratiques pour la conception de service Web
  • Une religion (RESTful, RESTlike, RESTafarians...)

REST par l’exemple§

Richardson Maturity Model§

Largement tiré du billet de blog de Martin Fowler.

_images/steps-towards-rest.png

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:

  • le service lui même (coté serveur), et
  • un client AJAX.

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.).

Niveau 0 : POX (Plain Old XML)§

_images/interaction-level0.png

POX - Échange 1§

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...).

POX - Échange 2§

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>

POX - Échange 2 (échec)§

HTTP/1.1 200 OK
[various headers]

<appointmentRequestFailure>
  <slot doctor="mjones" start="1400" end="1450"/>
  <patient id="jsmith"/>
  <reason>Slot not available</reason>
</appointmentRequestFailure>

Niveau 1 : Ressources§

_images/interaction-level1.png

Principe : exposer au client les ressources qui constituent le service (via différentes URLs).

Ressources - Échange 1§

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")

Ressources - Échange 2§

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>

Ressources - Remarques§

  • 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,

    • les URLs lisibles sont plus appropriables par les utilisateurs et les dévelopeurs,
    • les URLs de type “chemin” (“/”) permettent d’utiliser des URLs relatives.

Level 2 : Verbes et codes de status HTTP§

_images/interaction-level2.png

Principe : expliciter la sémantique de l’API via la sémantique de HTTP

HTTP - Échange 1§

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>

HTTP - Échange 2§

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 - Échange 2 (échec)§

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.

HTTP - Avantage§

  • Profite aux intermédiaires
    • bibliothèque HTTP coté client
    • serveur d’application coté serveur
    • proxy, firewall

digraph intermédiaires {
margin=0; rankdir=LR;

client -> intermédiaire -> intermédiaire2 -> serveur

intermédiaire2 [ label="..."; shape=none ]
}

  • Optimisation (gestion d’erreur, cache), selon la sémantique du verbe :
    • GET : idempotent, sans effet de bord
    • PUT, DELETE : idempotent, avec effet de bord
    • POST : non-idempotent, avec effet de bord

Level 3 : Hypermédia§

_images/interaction-level3.png

Principe : permettre au client de découvrir les actions possibles, plutôt que d’avoir à les connaître à l’avance.

Hypermédia - Échange 1§

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>

Hypermédia - Échange 2 (succès)§

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>

Hypermédia - Avantages§

  • Réduit le couplage entre client et serveur, en diminuant les connaissances a priori nécessaires coté client :
    • le client doit toujours “connaitre” le format XML,
    • mais plus la manière de construire les URLs.
  • Le serveur peut, sans “casser” les clients :
    • changer la structure de ses URLs,
    • déléguer certaines ressources à d’autres serveurs,
    • créer de nouvelles fonctionalités (en enrichissant le XML).

REST : le style architectural du Web§

Style architectural§

  • Notion proposée par Roy Fielding dans sa thèse (2000) : Architectural Styles and the Design of Network-based Software Architectures.
  • Défini comme un ensemble de contraintes imposées sur la conception d’un système pour garantir un certain nombre de propriétés.
  • La question sous-jacente était d’identifier les contraintes à respecter dans le développement du Web :
    • pour conserver les propriétés ayant fait son succès,
    • pour corriger les problèmes constatés,
    • pour évaluer les évolutions futures des technologies.

Objectifs§

« 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)

Passage à l’échelle§

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.

Généralité des interfaces§

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)

Déploiement indépendant des composants§

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)

  • e.g. : Mosaic → Netscape, CERN httpd → Apache

Composants intermédiaires§

Réduire la latence

  • en conservant en cache le résultat de certaines requêtes (proxy),
  • en répartissant la charge entre plusieurs serveurs redondants (reverse proxy).

Assurer la sécurité

  • en masquant l’accès à certains serveurs (proxy filtrant, reverse proxy, n-tiers).

Encapsulant des services

  • en adaptant les requêtes (gateway) ← généralité des interfaces

Contraintes§

Contraintes de REST, d’après Fielding :

  • client-serveur
  • connexion sans état (stateless)
  • support des caches
  • interface uniforme
  • système en couches
  • code à la demande (optionel)

NB: la description qui en suit doit beaucoup à Miguel Grinberg.

Client-serveur§

Separation of concern (Edsger W. Dikstra)

  • Le serveur est responsable du stockage et de la cohérence des données (état des ressources).
  • Le client est responsable :
    • de la présentation/du traitement des données,
    • de maintenir le contexte/état de l’interaction (cf. ci après).

Remarques :

  • Cette séparation peut être appliquée, même si le client et le serveur sont sur le même machine.
  • Certains composants sont à la fois client et serveur (e.g. proxy). Ils respectent cependant la séparation des préoccupations vis-à-vis des composants avec lesquels ils communiquent.

Note

Fournit “gratuitement” la possibilité d’avoir plusieurs clients.

Système en couches§

  • Cette contrainte spécifie qu’un composant ne doit se soucier que de ses interlocuteurs directs.
  • Le protocole HTTP assure lui même la cohérence des messages le long de la chaîne d’intérmédiaires en spécificiant, en fonction de leur sémantique, quelles parties d’une requête ou d’une réponse sont Hop-by-hop ou End-by-end.
  • Permet la mise en place de Composants intermédiaires.

Support des caches§

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).

Connexion sans état§

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

  • surcoût en bande passante
  • authentification à chaque requête (→ HTTPS)

Avantages

  • performances (un serveur / beaucoup de clients)
  • robustesse (redémarrage ou changement de serveur, clients nomades)
  • facilite le travail des intermédiaires
Remarques§
  • On parle bien ici de l’état du client. Le serveur gère évidemment l’état des ressources dont il a la charge.
  • Cette contrainte est souvent violée par les sites web (identifiants de session, cookies), censément pour améliorer
    • l’expérience utilisateur,
    • la sécurité (expiration des sessions).
  • Les sessions empèchent cependant
    • de bénéficier des caches,
    • de mettre un signet sur certaines pages,
    • de travailler en parallèle dans plusieurs onglets...

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.

Interface uniforme (1) : ressources§

  • Une ressource est un constituant du service (médecin, créneau horaire, rendez-vous, patient).
    • Une collection de ressource est aussi une ressource.
  • Toute ressource est identifiée par une URL.
    • Réciproquement, deux URLs différentes identifient (a priori) des ressources différentes.
  • Une ressource a un état interne (données stockées sur le serveur)
    • qui varie dans le temps,
    • et qui est inaccessible aux clients.

Interface uniforme (2) : représentation§

Une ressource n’est manipulée par le client qu’à travers des représentations de son état.

_images/MagrittePipe.jpg

Tableau de René Magritte - Source Wikipedia

_images/ombre-chinoise.gif

La représentation n’est pas nécessairement exhaustive.

Interface uniforme (3) : messages auto-suffisants§

  • La sémantique de la requête est entièrement portée par le message :
    • verbe (GET, PUT, POST, DELETE)
    • URL cible
    • en-têtes éventuels
    • représentation éventuelle
  • Très lié à Système en couches et Connexion sans état.

Interface uniforme (4) : hypermédia§

  • Hypertext As The Engine Of Application State (HATEOAS)
  • Notion d’affordance
_images/TheBigButton.jpg

Gary Larson

  • La représentation d’une ressource comporte les liens vers d’autres ressources (identifiées par leurs URIs).
  • La sémantique du lien dépend du format de la représentation.
  • L’état d’un client change en suivant les liens découvert dans les représentations.
  • NB : Une alternative consiste à construire un URI en fonction des informations fournies par une représentation. C’est le cas des formulaires HTML utilisant la méthode GET, e.g.:

    http://www.google.fr/search?q=hypertexte

Motivation sous-jacente§

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.

Code à la demande (optionel)§

  • Cette contrainte consiste à permettre au serveur d’envoyer au client non seulement la description d’un état, mais également une logique de traitement (programme).
  • On peut voir AJAX (Asynchronous Javascript and XML) et ses dérivés (JSON) comme une généralisation de ce principe (même si AJAX n’utilise pas forcément des échanges RESTful).

Discussions§

Représentation / Opérations§

Sémantique déclarative plutôt qu’opérationnelle

  • Alors que d’autres approaches (OOP, SOAP) mettent l’accent sur les opérations, REST fournit un ensemble pré-défini d’opétations (interface unifiée) et met l’accent sur les représentations.
  • La logique métier est donc principalement portée par le format des données échangées.

Analogie : les fichiers sous UNIX§

Une des évolutions majeures apportée par UNIX au domaine des systèmes d’exploitations a été l’unification de la notion de fichier :

  • un espace de nommage unique (le système de fichier)
  • une interface uniforme (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.

Cookies§

  • Un cookie est une chaîne de caractères associée au site, envoyée par le serveur, et que le client doit joindre à toute future requête sur ce serveur.
  • Le plus souvent, cette chaîne est un jeton opaque interprétable uniquement par le serveur (analogie aux fortune cookies).
  • respectent le principe d’auto-suffisance des requêtes
    • et préférable à un identifiant de session passé dans l’URL!
  • violent le principe de Connexion sans état
    • sauf mettre dans le cookie une description explicite, plutôt qu’un jeton opaque
  • changent a posteriori la sémantique des requêtes précédemment effectuées
    • « cassent » le bouton back et certains mécanismes de cache

Description des interfaces : le chaînon manquant§

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 :

  • vérification automatique de la conformité,
  • génération automatique de code (squelettes, stubs),
  • configuration automatique.

Il y a eu de nombreuses propositions dans ce sens :

Mais aucune ne s’est encore imposée...

Annexes§

REST : une alternative à SOAP§

SOAP : Simple Object Access Protocol

  • Une recommandation du W3C (2003) pour l’échange de données entre services Web (cf. séance précédente).
  • Poussée par des membres influents du consortium (Microsoft, Sun, IBM, Canon, Oracle).

Pourtant, SOAP recontre une certaine résistance

  • REST (Representational State Transfer), notion proposée en 2000 par Roy Fielding, est proposé comme une alternative.
  • En 2006, Google abandonne son API SOAP au profit d’une API simplifiée REST-like.

SOAP: Pas si « simple »...§

Une spécification volumineuse

  • Son ampleur décourage certains implémenteurs : pas d’implémentation complète dans certains langages (PHP, Python...).
  • Ce phénomène est amplifié par une profusion d’extensions (WS-Policy, WS-Security, WS-Trust, etc.)...
  • ... et le fait que leurs implémentations ne sont pas toujours homogènes.

SOAP est parfois perçu comme limitant paradoxalement l’interopérabilité des services Web.

SOAP: Pas si « Web »...§

Le succès du Web doit beaucoup à sa simplicité de mise en œuvre, simplicité qui fait défaut à SOAP.

  • cf. transparent précédent

Avec SOAP, le prototole HTTP est utilisé comme un simple protocole de transport.

  • C’est un choix délibéré (indépendance des couches, modèle OSI).
  • Pourtant, HTTP a été conçu comme un protocole applicatif.

→ SOAP se prive d’une grande partie des mécanismes du Web

Anatomie d’une requête HTTP§

L’« implémentation de référence » de REST.

Avertissement§

REST → HTTP mais

  • HTTP est largement implémenté.
  • Tout protocole RESTful serait amené à réinventer une grande partie de HTTP.
    • “any sufficiently sophisticated program implements a buggy subset of half a Common Lisp interpreter”

HTTP → REST

  • HTTP 1.1 comporte des compromis (compatibilité avec l’existant)
  • Il existe plusieurs manières d’utiliser HTTP, et toutes ne sont pas RESTful (e.g. SOAP).
  • Certaines extensions de HTTP sont « RESTless » (e.g. cookies).

Exemple de requête HTTP§

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

Exemple de réponse HTTP§

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)                                                        ...

Sémantique de la requête et de la réponse§

La requête consiste à appliquer un verbe à la ressource.

  • GET signifie ici « obtenir une représentation de la ressource ».
  • Le champs 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 .

  • Le code est suivi d’un libellé textuel pour améliorer la lisibilité.
HTTP/1.x 200 OK

Verbes§

HTTP définit quatre (principaux) verbes pour la manipulation des ressources :

  • GET : récupérer l’état de la ressource
  • PUT : attribuer l’état de la ressource
  • DELETE : supprimer la ressource
  • POST : fournir des données à la ressource

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).

Verbes (suite)§

Certains auteurs préfèrent caractériser les verbes HTTP simplement par rapport à leurs propriétés :

  • GET : idempotente, sans effet de bord
  • PUT, DELETE : idempotente, avec effet de bord
  • POST : non-idempotente, avec effet de bord

qui conditionnent le comportement des composants intermédiaires.

Codes de statut§

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

Identification§

Le client et le serveur donnent des indications sur leur identité et leur contexte.

  • Utile notamment pour les terminaux mobiles.
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

Négociation de contenu (1)§

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

Négociation de contenu (2)§

  • Si aucune représentation disponible ne peut satisfaire le client, le serveur peut retourner une code 406 Not Acceptable.
  • Il doit normalement fournir dans la réponse une liste des représensentations disponibles.
  • L’agent (logiciel client) est autorisé à sélectionner automatiquement l’une de ces représentations.
  • Cette information peut également être fournie dans l’entête de la réponse (non standard).

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}}

Méta-données de cache (1)§

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.

Méta-données de cache (2)§

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 :

  • pour spécifier sa tolérance à la « vieillesse » de la réponse,
  • pour forcer un rechargement:
Cache-Control: no-cache

Méta-données de connexion§

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