Skip to content

Instantly share code, notes, and snippets.

@jgrenat
Last active August 29, 2015 14:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jgrenat/2fcfe1a2c774c13e2466 to your computer and use it in GitHub Desktop.
Save jgrenat/2fcfe1a2c774c13e2466 to your computer and use it in GitHub Desktop.
Rest World - Best of Web

Rest World - Best of Web

J'ai récemment eu l'occasion d'assister à la conférence Best of Web, la réunion de tous les plus grands meetup parisiens. Vous pouvez retrouver le déroulement et le programme global de cette journée sur cet article de Stéphane Blanchon.

Dans cet article, je vais parler d'une conférence qui m'a particulièrement intéressé, étant très sensible au sujet des API Rest. J'en développe en effet quotidiennement dans mon travail au sein de Viseo. Il s'agit de la conférence de Virginie Bardales intitulée - vous l'aurez deviné - Rest World.

Qu'est-ce qu'une API Rest ?

Avant de définir une API Rest, l'experte de ce domaine a commencé par définir ce qu'était une API - pour Application Programming Interface. Il s'agit de ce qu'expose une application (au sens très large du terme) au monde extérieur pour accéder à ses données, voire permettre de les manipuler.

Dans cette définition, elle intègre les API SOAP, les documentations qu'on peut trouver sur internet, et les sites web eux-mêmes. En effet, les pages web ne sont rien d'autre que des données exposées, structurées sous forme de DOM.

REST est un type d'architecture d'API orienté services, et qui contient plusieurs niveaux de définition. Une API REST expose un ensemble de ressources et permet d'effectuer diverses opérations dessus. Au-delà de cette définition, la conférencière rappelle les différentes caractéristiques de ce type d'architecture. Une API REST est :

  • client-serveur : on ne se préoccupe pas de la persistance ;
  • stateless : on ne gère pas de sessions, on peut donc très facilement dupliquer nos serveurs pour supporter la charge ;
  • uniforme : le protocole utilisé est universel ;
  • mutable : facile à modifier et entretenir ;
  • performante : le protocole utilisé permet de bonnes optimisations, notamment avec un cache finement géré ;
  • portable : le protocole étant universellement utilisé, une API REST peut être consommée depuis une grande variété de devices.

La présentatrice définit ensuite ce que sont les six niveaux de formalisation d'une API REST, chacun de ces niveaux pouvant être vu comme une étape de maturité d'une API REST.

Niveau 0

Le niveau 0 - le niveau par défaut - ne contient qu'une seule règle : l'utilisation du protocole HTTP. Le protocole HTTP est celui utilisé par les sites web. Il offre des méthodes HTTP, des headers HTTP et des codes HTTP qui vont nous permettre de donner du sens à notre API.

Il est en outre très utilisé, supporté aussi bien par les ordinateurs que les portables, les tablettes, de nombreux objets connectés, ... Sa spécification est également très bien définie. Quand des web services SOAP sont exposés via HTTP, on peut donc déjà parler d'API REST. Cependant, il faut garder à l'esprit que ce niveau définit une base pour les niveaux ultérieurs et n'impose donc pas l'utilisation des headers, des méthodes ou des codes retour HTTP ; il spécifie uniquement que le protocole utilisé est HTTP.

Niveau 1

Le niveau 1 ne contient également qu'une seule règle : une ressource est accessible par une et une seule URI. Pourquoi cette règle ? Simplement parce que les URI sont également universelles, et que cela permet de ne pas avoir d'état dans l'adresse.

Quelle que soit la manipulation qu'on souhaite effectuer sur une ressource, on saura donc toujours sur quelle adresse envoyer notre requête. Cette adresse répond à quelques critères :

  • il vaut mieux utiliser des noms que des verbes ;
  • pour les noms composés, il vaut mieux s'en tenir aux minuscules et utiliser des tirets ;
  • pour cibler un objet précis, on utilise au maximum des ID permanents et uniques ;
  • on évite de faire varier ce nom, notamment entre pluriel et singulier.

S'il peut être tentant d'utiliser du pluriel pour les listes d'objets, puis du singulier pour un élément de ces listes, cela est déconcertant pour le consommateur de l'API qui doit s'interroger sur de telles règles. Virginie Bardales recommande donc de faire un choix entre singulier et pluriel, puis de s'y tenir. Exemples d'URI :

La présentatrice propose aussi une ouverture vers les UPRI, qui sont des URI contenant aussi des termes lisibles statiques et uniques. Par exemple : http://www.client-api.com/client/1-**marcel-dupont**.

Pour tout ce qui concerne l'intelligence (format de retour, pagination, etc...), elle recommande d'utiliser les paramètres GET :
http://www.client-api.com/clients**?page=3&format=json**.

REST niveau 2

Comme on ne peut pas stocker les actions dans l'URL, on utilise une fonctionnalité très pratique du protocole HTTP : les méthodes HTTP.

La conférencière présente bon nombre de ces méthodes :

  • GET : permet de récupérer les données, sans les altérer ; c'est une requête nilpotente (elle ne modifie pas les données) ;
  • DELETE : permet de supprimer la ressource ; c'est une méthode idempotente (chaque appel produit le même résultat) ;
  • PUT : sert à écrire (modifier, créer) une ressource dans sa globalité ; c'est également une méthode idempotente ;
  • POST : suivant les cas d'utilisation, provoque un changement de la ressource ou en crée une sans spécifier l'ID ; ce n'est pas une méthode idempotente ;
  • PATCH : sert à mettre à jour partiellement les données ; elle n'est pas idempotente ;
  • OPTIONS : retourne les méthodes supportées ; elle est nilpotente ;
  • HEAD : retourne l'en-tête que retournerait une méthode GET sans les données ; elle est également nilpotente.

L'utilisation de ces méthodes donne du sens à nos requêtes et permet de savoir exactement le type d'opération effectuée.

REST niveau 3

C'est le niveau auquel on fait référence quand on parle de Restful. De fait, c'est le niveau le plus connu et pourtant rarement atteint d'une API. Respecter le niveau 3 revient donc déjà à avoir une API très mature et très bien formalisée.

Le principe est simple : on ne doit jamais avoir à deviner comment accéder à une ressource en particulier, ni même ignorer les relations entre les ressources. Pour cela, on ajoute à nos retours des méta-informations permettant d'avoir les URI des différentes ressources (y compris la ressource courante). Virginie Bardales propose d'utiliser la contrainte HATEOAS. Certains clients permettent de tirer automatiquement parti de ces méta-informations supplémentaires (comme par exemple le framework Backbone.js). On peut par exemple rajouter dans le retour d'un GET sur une URI http://www.client-api.com/client/1 les données suivantes (si on est en format JSON) :

{
	...
	"_links": {
		"self": "http://www.client-api.com/client/1",
		"address": "http://www.client-api.com/client/1/address"
	}
}

Sur une collection paginée, on peut également rajouter l'URI de la page précédente, de la page suivante, etc...

Cette liste d'URI peut également se faire dans un header HTTP Link pour éviter de polluer le corps de la réponse. Dans ce cas, on peut même aller plus loin en ne fournissant qu'un seul lien relatedData sur lequel l'utilisateur pourra ensuite exécuter une requête HEAD afin de récupérer en en-tête la liste des liens liés à cette ressource. On déborde d'ailleurs ainsi sur le niveau 4.

La dernière recommandation pour atteindre le niveau 3 consiste à utiliser correctement les codes HTTP en réponse. Ceux-ci permettent en effet une incroyable diversité dans les réponses et sont - encore une fois - universellement connus. Parmi les plus connus, on peut citer le code 200 (la requête a été exécutée avec succès), le code 404 (ressource non trouvée) et le code 500 (le serveur a connu une erreur interne). Tous les codes HTTP et leur signification sont listés sur ce lien.

REST niveau 4

Au niveau 4 d'une API REST, on utilise les headers HTTP pour transmettre toutes sortes de méta-informations. On peut par exemple spécifier la version de l'API, les formats accessibles en sortie, les pages qu'on souhaite récupérer. Il faut cependant faire attention : tous les clients ne supportent pas très bien les headers HTTP. Cela peut être pallié en acceptant explicitement certains headers grâce aux CORS. Voici un des exemples donnés pendant la présentation :

GET /my/data HTTP/1.1 Host: example.org Range: data 3-7 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 ...

REST niveau 5

Le niveau 5, moins expliqué durant la conférence, réintroduit des notions métier dans nos URI. On utilise les méthodes appropriées et des verbes dans nos URI pour spécifier des actions qui ne seraient pas explicites uniquement avec les autres niveaux REST. Cela se fait évidemment en plus des règles des autres niveaux. Par exemple pour une requête POST afin de publier un article :

http://www.blog-api.com/article/1/**publier**

Conclusion

Bien que déjà au courant de beaucoup de ces bonnes pratiques, je n'avais jamais eu l'occasion de les voir aussi bien explicitées. Cela peut certes demander beaucoup de travail, mais les API qui respectent au moins une partie de ces règles s'avèrent bien plus utilisables.

C'est donc un ensemble de bonnes pratiques dans lesquelles il faut puiser avec soin pour améliorer nos API avec les moyens dont nous disposons sur les projets, tant au niveau du temps que des limites techniques.

Lien vers les slides de la présentation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment