Professional Documents
Culture Documents
Par exemple, pour trouver la description d’un produit grâce à une référence internationale upc
(Universal Product Code), on pourrait avoir quelque chose de ce style avec XML-RPC (ancêtre de
soap) et le langage ruby.
require 'xmlrpc/client'
server = XMLRPC::Client.new2('http://www.upcdatabase.com/rpc')
response = server.call('lookupUPC', "737052003306")
puts response[‘description’]
# => affiche la description du produit avec l’upc 737052003306
# => ici : « Hugo Boss Boss Selection - Eau de Toilette Spray 50 ml »
Avec tcpmon, on verrait donc quelque chose de ce genre dans le corps de la méthode POST
REST (Representational State Transfert) part d’un autre point de vue centré sur la ressource (dans
l’exemple au dessus cette ressource est le produit). Les verbes nécessaires pour créer un service
peuvent se réduire à Créer, Lire, Mettre à jour et Supprimer cette ressource. C'est-à-dire que les
seuls services (au sens opération dans soap) dont on a besoin dans une application sont des services
CRUD (Create, Read, Update, Delete en anglais).
Ceci réduit considérablement les possibilités au point de dire que les méthodes http seules peuvent
indiquer notre intention. Ainsi la méthode http GET permet de lire la ressource, POST/PUT
permettent de créer ou mettre à jour, DELETE permet de supprimer.
SMB111 – SYSTEMES ET APPLICATIONS REPARTIS
En fait REST exploite à 100% les méthodes http, ce qui n’est pas le cas des protocoles comme soap
qui n’utilise que la méthode POST pour fonctionner. De plus REST interdit la création de nouveau
verbes.
Ainsi, si on respecte les principes REST, une requête qui permet de récupérer la description d’un
produit avec sa référence upc ressemblerait à
require 'open-uri'
upc_data = open('http://www.upcdatabase.com/upc/737052003306').read()
Ici on a remplacé la méthode POST utilisée par XML-RPC (voir plus haut), par une méthode GET, ce
qui est plus léger en nombre de lignes de code et en nombre de caractères qui circulent sur le
réseau.
Ce que l’on fait ici c’est accéder à la ressource (le produit), par son URL (Uniform Ressource Locator)
en récupérant sa représentation.
Quel design pattern vu en cours pourrait-on utiliser pour traiter une requête http et choisir une
(re)présentation pour la réponse ?
Dans tous les cas la différence dans la réponse avec un protocole de type SOAP, c’est que nous ne
récupérons que l’information nécessaire. Il n’y a plus toutes les balises nécessaires au
fonctionnement de soap.
Cette manière de faire des services web est toutefois trop récente et subtile. Elle demanderait
beaucoup plus d’explications pour être parfaitement enseignée. Cette partie du cours a juste la
prétention de vous faire connaitre cette manière de faire des services web.
J’ai complété le cours avec un très bon article issu du web et qui devrait vous permettre de
commencer à percevoir cette manière de « penser » les services web qui s’oppose à tout ce que nous
avons vu jusqu'à présent.
N.B. : dans l’article le terme API (Application Programming Interface) est utilisé, vous pouvez
remplacer ce terme par « service web SOAP », ceci peut aider à la compréhension.
SMB111 – SYSTEMES ET APPLICATIONS REPARTIS
SOURCE DE L’ARTICLE:
http://www.biologeek.com/rest,traduction,web-semantique/pour-ne-plus-
etre-en-rest-comprendre-cette-architecture/
Si vous essayez de comprendre REST, cette série est faite pour vous.
Les experts en HTTP, HTML et REST pourraient chercher la petite bête avec ma terminologie simplifiée me
permettant d'aller droit au but. Si c'est votre cas, je ne veux pas en entendre parler, car cette série ne vous est
pas destinée de toute façon :-)
PREMIER POINT
Commençons par le commencement. Comment fonctionne un navigateur ? Avant d'essayer de
développer des sites avec Rails, je pensais que ça marchait ainsi :
En réalité, le protocole HTTP décrit les instructions détaillées de la façon dont un navigateur doit
envoyer ses requêtes au serveur. HTTP est totalement différent du HTML, qui est le langage choisit
pour représenter le contenu d'une page. HTTP permet au navigateur de récupérer divers types
d'informations à partir du serveur, dont la simple récupération d'une page HTML ou la soumission d'un
formulaire. En fait, HTTP permet d'effectuer huit types de requêtes différentes sur le serveur. Les deux
requêtes les plus connues sont les suivantes :
une requête « GET » : récupère le contenu d'une ressource sur le web, la ressource est
uniquement identifié par une URL ;
une requête « POST » : envoie des données à une URL afin de créer une nouvelle ressource.
SMB111 – SYSTEMES ET APPLICATIONS REPARTIS
DEUXIEME POINT
Remarquez comme j'ai glissé le mot « ressource » alors que vous ne l'attendiez pas. Ça a été mon
premier mal de tête lorsque j'ai essayé de comprendre REST : penser au web comme un ensemble
de ressources, pas de « pages web ». Qu'est-ce que je veux dire par là ?
Hier, je suis allé sur amazon.com et j'ai consulté quelques produits que je voudrais acheter. J'ai
aussi lu quelques articles de Wikipedia. J'ai parcouru quelques news de TechCrunch et j'ai ensuite
vérifier les scores de D1 pour constater à quel point Lyon est loin devant.
Si vous voulez comprendre REST, vous devez arrêter de penser à tout ça en termes de pages
web. Prenons l'exemple d'un article de Wikipedia. Ce n'est pas seulement une page web, c'est une
ressource - dans notre exemple une biographie d'Archimède. J'utilise un navigateur web pour accéder
à cette ressource, le navigateur récupère donc une représentation HTML de cette ressource, car
afficher du HTML est la seule possibilité de représentation de ces ressources par un navigateur.
Je sais que c'est étrange au début. L'article sur Archimède n'est pas une page web ? Non. J'ai
demandé la représentation HTML d'une ressource appartenant à Wikipedia, une ressource pouvant
être identifiée par l'URI « //fr.wikipedia.org/wiki/Archimède ». Wikipedia aurait pu choisir de
représenter cette ressource de beaucoup de façons - avec un PDF, ou peut-être une image .jpg. C'est
même peut-être déjà possible. Mais Firefox utilise une requête GET qui spécifie que cette ressource
doit être obtenue à partir du serveur sous forme de HTML, donc c'est ce que j'ai.
Un autre exemple : ma réservation d'avion est une ressource détenue par Air France. Ils me
permettent d'accéder à cette ressource de diverses manières : via une page HTML, mais ils peuvent
aussi envoyer les informations de ma réservation sur mon téléphone portable. Ou ils peuvent me
l'envoyer par mail en texte brut. Ou je peux les appeler avec un outil obsolète et ils vont me le dire de
vive voix. Une même ressource, plusieurs représentations.
J'espère que c'est clair maintenant : ma réservation d'avion n'est pas qu'une page web. C'est
une vraie ressource qui (heureusement pour moi) peut être affichée en HTML lorsque je le désire, et
je peux utilise mon navigateur pour demander cette représentation et l'afficher sur mon écran.
TROISIEME POINT
Ok, maintenant que vous avez accepté le fait que le web est une gigantesque collection de
ressources qui peuvent être servies de différentes manières, et qu'un affichage HTML est juste
l'une d'entre elles, il y a maintenant un dernier concept que je souhaite aborder. Les ressources ne
sont pas uniquement des simples articles biographiques, ou des réservations d'avions, ou des
résultats sportifs. Certaines ressources sont des collections d'autres ressources. Une liste de
vacances peut être une ressource. Une liste d'amis peut être une ressource. Une série de billets de
blog peut être une ressource.
Maintenant que vous avez compris ce que sont les ressources, nous allons maintenant nous
intéresser à la façon dont HTTP permet la création, la récupération, la mise à jour et la suppression
des ressources (NdT : bon normalement c'est crud pour create, retrieve, update etdelete).
SMB111 – SYSTEMES ET APPLICATIONS REPARTIS
DES MILLIONS D'API
ANALYSE ORIENTEE OBJET ET DESIGN
Si vous programmez en orienté objet depuis un certain temps, vous avez probablement appris à
procéder de la façon suivante :
écrire une description de votre problématique - ce que votre programme est censé faire.
les noms sont vos classes.
les verbes sont les méthodes de vos classes.
permettre à vos noms d'appeler les méthodes d'autres noms pour qu'ils accomplissent des tâches.
Ça semble bon. C'est ce que je fais en programmation depuis un moment déjà. Ce type de
programmation par nom-verbe est souvent appelé style RPC. Je ne sais pas en quoi c'est proche de
l'accès à distance mais je sais juste que le style RPC est la façon « classique » de développer des
logiciels avec de l'orienté objet. C'est une très bonne manière pour développer des logiciels mais ce
n'est pas la façon dont le web a été pensé. Pourquoi ça ?
Imaginez-vous en 1992 (ou juste avant que le web soit tel que vous le connaissez aujourd'hui).
Et supposez 3 équipes différentes qui développent 3 logiciels : un pour acheter des livres, un pour
acheter des billets d'avion et un autre qui permet d'obtenir des photographies aériennes de n'importe
quelle distance de la Terre. Elles suivent toutes les 3 les techniques de modélisation orientée objet
classiques dont nous avons parlé pour développer leurs applications. Et pensant qu'un tiers voudra
probablement un jour s'interfacer avec leur logiciel, elles vont aussi implémenter leurs propres API.
Maintenant supposons que ce soit votre boulot d'écrire un outil qui soit une interface de ces 3
applications.
Ugh. Vous allez devoir apprendre 3 API différentes. Et je parie que vous voudriez des boutons
qui correspondent directement aux méthodes que vous appelez pour chaque API. Ça semble logique,
non ? Je veux dire, comment feriez-vous autrement ? Ok, on ne parle que de 3 API et vous
connaissez de bon ouvrages qui ont des design patterns qui vont vous permettre de réduire cette
complexité (et de rester aimable avec vos collègues par la même occasion).
Est-ce magique ? Réfléchissez un moment à l'impossibilité d'une telle approche si chaque site
avait sa propre API. Pour acheter un livre sur Amazon, le navigateur aurait dû savoir appeler la
méthode Amazon.Acheter(). Et il aurait dû appeler la méthode AirFrance.VérifierVols() lorsque j'ai
cliqué sur le bouton « Vérifier les vols ». Vous ne pouvez tout simplement pas développer un outil qui
permette d'appeler des millions d'API différentes.
SMB111 – SYSTEMES ET APPLICATIONS REPARTIS
C'est la raison pour laquelle le web n'a pas été designé avec une architecture RPC. Il a été
designé avec une architecture REST.
ARCHITECTURE RESTFUL
NOUS SOMMES LES DEPOTS
À partir de maintenant, pensez à votre application comme étant rien d'autre qu'un dépôt à
ressources. Qu'est-ce qu'un dépôt ? Subversion est un bon exemple de dépôt de code source.
MySQL est un dépôt de données relationnelles. Vous pensez à d'autres exemples ?
Pour le moment, j'ai juste besoin de prendre un exemple de dépôt que l'on puisse utiliser dans la
suite de ce billet.
Laissez-moi le répéter, au cas où vous ne m'auriez pas entendu avec le raffut que font vos
marqueurs effaçables, car c'est vraiment important.
Dans notre exemple, je peux rapidement identifier quelques noms clés : avions, aéroports et
vols. Je vais probablement en trouver davantage ensuite mais c'est déjà un bon début.
Comment les interfaces clients vont-elles accéder à chacune de ces ressources ? Les URL ont
été inventées pour ça. (Vous savez ce que signifie le L de URL n'est ce pas ?) Le « localisateur » de
chaque ressource suit un pattern simple. Par exemple :
/aeroports pour la liste des aéroports
/avions pour la liste des avions
/vols pour la liste des vols
et :
QUATRE METHODES
Ok, une fois vos ressources identifiées, REST définie les 4 méthodes (ou verbes en langage HTTP)
que chacune de vos ressources peuvent implémenter :
GET : donnez moi une vue en lecture seule d'une instance d'une ressource depuis le dépôt.
POST : j'ai une nouvelle instance d'une ressource que je veux ajouter au dépôt.
PUT : je veux mettre à jour une ressource existante dans le dépôt.
DELETE : je veux supprimer une instance d'une ressource du dépôt.
Ça vous semble familier ? Avec Subversion, GET est similaire aux commandes « checkout » ou
« update ». POST correspond à la commande « add » et DELETE à « delete ». Dans l'exemple avec
MySQL, GET revient à faire un SELECT, POST un INSERT, PUT est semblable à UPDATE et
DELETE, et bien, DELETE.
Wow. Nous avons nos ressources et nous avons nos méthodes. On peut arrêter ici le design et
commencer l'implémentation.
Vous pouvez aussi appeler la méthode POST à partir de votre navigateur - mais seulement s'il y
a un formulaire <form> sur la page. (Ok, pas exactement grâce à AJAX mais oublions pour le
moment). Les formulaires peuvent envoyer des données à une URL particulière. Lorsque vous
soumettez un formulaire, le navigateur appelle la méthode POST, passant l'URL ainsi que certaines
données représentant la ressource qu'il doit ajouter ou modifier.
Vous ne pouvez pas appeler PUT ou DELETE avec votre navigateur avec du HTML
habituel. Ce qui est bien malheureux. Bien que chaque serveur HTTP dans le monde sache gérer les
appels aux méthodes PUT et DELETE, il n'y a pas de procédure standardisée pour faire ces appels
avec du HTML. Vous devez inventer votre propre façon de faire pour signaler au serveur que vous
essayer de faire des appels à PUT ou DELETE.
En résumé : vous pouvez faire correspondre votre API REST avec les verbes HTTP mais il
n'y a aucun tag HTML qui permette de faire des appels à PUT ou DELETE. Le client et le serveur
doivent se mettre d'accord sur une convention à utiliser pour simuler les méthodes PUT et DELETE.
ON Y EST PRESQUE
Maintenant que notre design est au point, nous l'implémenterons prochainement avec RailsDjango ;-).
REACTIONS DU TRADUCTEUR
Bon vous l'aurez compris, les prochains billets ne seront pas des traductions d'exemples
d'implémentation avec Ruby on Rails mais des articles originaux pour voir ce qu'il est possible de faire
avec Django. Plusieurs projets ont vu le jour et vont tenter de s'unifier pour arriver à une solution
cohérente et facilement intégrable. Bon accessoirement, j'aimerais bien mettre en place
professionnellement une telle architecture donc ça m'intéresse beaucoup.