Développer une API RESTful
REST signifie « Representational State Transfer », c’est un standard d’architecture fonctionnant autours de ce qu’on appelle des ressources.
Une API RESTful respecte ce standard et ses contraintes, elle permet ainsi à n’importe qui de comprendre rapidement son fonctionnement.
Une API REST s’intègre parfaitement dans le protocole HTTP, les entêtes de la réponse HTTP doit contenir toutes les informations que le client peut avoir besoin pour interpréter son état, sans nous attarder sur cette contrainte, nous allons voir comment développer une API REST.
Format de requête et réponse
Le format le plus commun pour faire du REST, c’est le JSON, ainsi le corps de votre requête ne sera pas au format habituel qu’utilise un navigateur (application/x-www-form-urlencoded) mais aura pour Content-Type celui du JSON (application/json). De même quand vous récupérer un objet dans une réponse HTTP, le retour est le Content-Type du JSON.
Envoyer des requêtes CRUD RESTful
Il faut bien comprendre que c’est le chemin de la requête qui identifie la ressource et qu’une requête est idempotente, la même requête doit toujours renvoyer le même résultat et ne pas varier selon un contexte implicite, elle peut cependant varier selon un paramètre.
Avant de continuer, sachez qu’il est crucial d’utiliser un système d’authentification, il ne s’agît pas de renvoyer toutes nos données à n’importe quelle personne qui utiliserait notre API.
Lister des objets d’une ressource
GET /ressource
Une requête de type GET sur une ressource sans identifiant permet de récupérer une collection d’objets et par défaut, tous les objets de cette ressources, le résultat attendu est donc forcément une liste. Vous pouvez filtrer et trier vos résultats en envoyant des paramètres Query.
Créer un objet d’une ressource
POST /ressource
La méthode POST signifie explicitement qu’il s’agit d’une création et dans une API RESTful, on ne peut créer qu’un seul objet à la fois. Si la même requête est appelée à nouveau, elle recréera l’objet une nouvelle fois, sauf si vous vérifiez côté serveur qu’il n’y a pas de doublon. Elle retourne généralement le nouvel objet créé.
Récupérer un objet d’une ressource
GET /ressource/1024
Si un identifiant est précisé et que la méthode GET est utilisé, cela signifie que nous souhaitons récupérer précisément l’objet avec cet identifiant. Dans une API RESTful, l’objet retourné doit toujours être complet et seul cet objet doit être retourné, ni ses relations, ni ses sous-ressources.
Modifier un objet d’une ressource
PUT /ressource/1024
Si un identifiant est précisé, la méthode PUT spécifie alors que nous souhaitons modifier cet objet, le nouvel objet est passé dans le corps de la requête. Elle retourne généralement le objet modifié.
Supprimer un objet d’une ressource
DELETE /ressource/1024
Si un identifiant est précisé, la méthode DELETE demande la suppression de cet objet.
Renvoyer un code d’erreur
Le code HTTP de la réponse doit varier pour s’adapter à l’erreur qui est survenue, on peut aussi renvoyer une chaîne de caractère comme body afin de donner plus de détails sur l’erreur. Parfois, on s’autorise à renvoyer du JSON par facilité, il faut alors s’assurer que l’objet retourné est toujours du même type.
Détails
Nommer sa ressource
Une ressource peut être nommée au singulier ou au pluriel, cela dépend des écoles, pour ma part, je trouve logique de n’utiliser que le singulier. Par défaut, une ressource prend le nom de l’objet qu’elle retourne mais il est conseillé de le faire varier selon le contexte, surtout comme sous-ressource. Ainsi, on écrira GET /user
pour récupérer l’ensemble des utilisateurs mais, on pourra écrire GET /user/128/friend
pour récupérer tous les amis de l’utilisateur 128 ou GET /user/128/family
pour récupérer les membres de sa famille.
L’utilisateur authentifié
Vous devez limiter l’accès aux données selon les droits de l’utilisateur authentifié, il possédera ainsi généralement beaucoup de sous-ressources, on le nomme généralement /me, une sorte d’alias de l’utilisateur authentifié.
Ainsi GET /me
récupèrera l’utilisateur courant, PUT /me
le modifiera… Et on pourra avoir GET /me/friend
pour récupérer la liste de ses amis, GET /me/cart
pour récupérer son panier…
Accéder aux sous-ressources
Vous remarquez avec tout ça qu’on peut accéder à une ressource par son chemin de ressource GET /picture/123
ou par son chemin de sous-ressource GET /me/picture/123
, la question est de savoir si la ressource parente est obligatoire ou optionnelle.
L’exemple donné est celui des photos d’un utilisateur :
- Si on souhaite que n’importe quel utilisateur, même non connecté, puisse accéder aux photos de tous les utilisateurs alors le chemin
/picture/123
est le plus pertinent. - Si on souhaite qu’un utilisateur ne puisse accéder qu’à ses photos, on aura alors
/me/picture/123
(ma photo avec l’identifiant #123), si cette photo n’existe pas ou n’est pas à moi, il vous faut renvoyer une erreur 404. - Si on souhaite qu’un utilisateur ne puisse accéder qu’aux photos de ses amis, il faudrait alors utiliser
/me/friend/321/picture/123
(la photo avec l’identifiant #132 de notre ami avec l’identifiant #321). Vous pouvez permettre d’accéder aux photos par plusieurs chemins mais il faut que ça reste logique et pertinent.