Aller au contenu

Les bonnes pratiques dans la conception d'un API

Utiliser le format JSON

Le format à préconiser pour recevoir et retourner de l'information de notre api est le format JSON. C'est de loin le plus utilisé aujourd'hui et la grande majorité des langages de programmation on des fonctions natives pour le manipuler.

Plus de détail dans cette section : Le format JSON

Utiliser des noms au lieu de verbes pour les routes

Quand on nomme les routes de notre api, on ne devrait pas utiliser de verbe. L'emploi d'un nom significatif est à privilégier. Par exemple notre api nous permet de retourner une liste d'utilisateurs ou d'en créer un, on serait tenté d'utiliser comme nom de route

https://monApi/getUtilisateurs
https://monApi/createUtilisateurs

mais il est préférable d'utiliser dans les deux cas

https://monApi/utilisateurs

Une même route peut avoir plus d'une fonctionnalité, c'est la méthode HTTP qui nous permet de les différenciées.

Utiliser de paramètres directement dans l'url

Vous pouvez inclure des paramètes dans la route des deux façons suivantes :

Dans la section query de l'url :

https://monApi/utilisateurs?code=1
Cette méthode permet d'ajouter facilement plusieurs paramètres.

Directement dans la route

https://monApi/utilisateurs/1
Cette méthode ne devrait pas être utilisé avec plus d'un paramètre. Vous devez aussi faire attention à ne pas créer de confusion avec d'autres routes.
https://monApi/utilisateurs/1
https://monApi/utilisateurs/tous
Dans cette exemple, selon l'ordre que les routes seront traitées dans le code, la deuxième pourrait ne jamais être accessible.

Utiliser la méthode HTTP pour décrire la fonctionnalité de la ressource

En lien avec le point suivant, utilisez la bonne méthode HTTP pour indiquer quelle est la fonctionnalité de la route. Il existe une méthode qui correspondante à chaque opération CRUD.

Opération dans la BD Méthode http
Lire GET
Insérer POST
Modifier PUT
Modifier partiellement PATCH
Supprimer DELETE

Attention

On ne doit jamais modifier une ressource avec une méthode GET.

Les actions de modification PUT et PATCH sont très similaires, la différence est que PUT est utilisé pour modifier toutes les valeurs de la ressource alors que PATCH l'est pour une modification partielle. Autre distinction de PUT, si la ressource n'est pas trouvé, elle sera créée. Prenons l'exemple suivant, on veut pouvoir modifier un utilisateur ayant ces informations

{
    "id" : "1",
    "username" : "[username]",
    "first_name" : "[first_name]",
    "last_name" : "[last_name]",
    "email" : "[email]"
}

Avec PUT on doit envoyer toutes ces informations dans la requête, alors qu'avec PATCH on pourrait permettre seulement d'envoyer et de modifier le email.

L'utilisation de la bonne méthode HTTP nous permet d'avoir le même nom de route pour plus d'une fonction.

Méthode Route Description
GET /utilisateurs Retourne la liste de tous les utilisateurs
POST /utilisateurs Création d'un utilisateur
PUT /utilisateurs/21 Modification de l'utilisateur avec le id 21
DELETE /utilisateurs/21 Suppression de l'utilisateur avec le id 21

Utiliser les codes de statut HTTP

Dans la réponse de la requête à votre API utilisez une code de statut HTTP approprié à la situation.

  • 200 - 299 indique un succès
  • 400 - 499 Il y a eu une erreur côté client
  • 500 - 599 Il y a eu une erreur côté serveur

Résumé des méthodes avec le code de statut suggéré

Méthode GLOBAL (/utilisateurs) Sur un element (/utilisateurs/{id})
POST 201 Created - La ressource est créée et est retournée dans la réponse -
GET 200 OK 200 OK
404 Not Found - La ressource n'a pas été trouvée, ex: le id utilisateur est invalide.
PUT 405 Method Not Allowed - On ne devrait pas permettre de modifier toutes les ressources en une action 200 OK - La ressource est modifiée et est retournée dans la réponse.
201 Created - La ressource a été créé car elle etait inexistante.
PATCH 405 Method Not Allowed - On ne devrait pas permettre de modifier toutes les ressources en une action 200 OK - La ressource est modifiée et est retournée dans la réponse.
404 Not Found - La ressource à modifier n'a pas été trouvée, ex: le id utilisateur est invalide.
DELETE 405 Method Not Allowed - On ne devrait pas permettre de supprimer toutes les ressources en une action. Si oui utilisez le code 200. 204 No Content - La ressource a été supprimé et aucune information n'est retournée dans la réponse.
200 OK - La ressource est supprimé et est retournée dans la réponse.
404 Not Found - La ressource à supprimer n'a pas été trouvée, ex: le id utilisateur est invalide.

Codes à utiliser pour les erreurs

Code Utilisation
401 - Unauthorized Le client ne s'est pas encore authentifier pour accéder à l'api.
403 - Forbidden Le client est authentifié mais n'a pas les autorisations pour accéder à la ressource.
404 - Not Found L'url utilisé est invalide, le client demande une ressource qui n'existe pas.
500 - Internal Server Error Une erreur est survenu côté serveur. Retournez de l'information sur l'erreur dans la réponse.

Utiliser l'imbrication dans les routes

Quand des ressources de votre api peuvent être reliées, utilisez l'imbrication pour créer des urls significatifs. Par exemple un auteur peut avoir écrit plusieurs livres, on pourrait avoir une route nommée /{auteurs}/livres qui retourne tous les livres de l'auteur en paramètre.

Il faut cependant faire attention à ne pas trop surcharger la route en allant trop profondément avec l'imbrication.

Permettre les filtres, le tri, sélection des champs retournés et la pagination

Pour permettre à l'utilisateur un meilleur contrôle sur les données récupérées, permettez quand c'est possible l'utilisation de filtres, de tri et de pagination dans vos requête. Les paramètres devraient être situé dans la section "requête" de l'url

Filtre

Utilisez un nom de paramètre significatif. Pour saisir plusieurs valeurs à un même paramètre, on doit les séparer par une virgule.

Exemple :

  • /livres?categorie=roman pour afficher tous les livres de la catégorie roman.
  • /livres?categorie=roman,documentaire pour afficher tous les livres de la catégorie roman et documentaire.

tri

Utilisez comme valeur du paramètre le nom du champ avec un code prédéfini en préfixe ( + et - par exemple) qui indiquera si le tri est ascendant ou descendant. Le tri sur plus d'un champ devrait aussi être permis.

Exemple :

  • /livres?tri=+titre,-prix pour trier par les livres titre de manière ascendante et par prix de manière descendante.

Sélection des champs retournés

Il peut aussi être pertinent de permettre au client de pouvoir sélectionner uniquement les champs qu'il veut avoir dans la réponse à la requête.

Exemple :

  • /livres?champs=titre,isbn retournera la liste de tous les livres mais seulement le titres et isbn de chacun.

Pagination

Il n'est pas rare qu'une ressource comporte plusieurs centaines sinon milliers d'enregistrements. On devrait permettre au client de pouvoir sélectionner seulement une partie des enregistrements en définissant un point de départ (offset) et un nombre d'enregistrement (limit). Si on utilise la pagination, on devrait définir des valeurs par défaut au paramètre offset et limit (généralement offset sera égale à 0 pour le premier enregistrement).

Exemple :

  • /livres?limit=50&offset=100 En partant du centième enregistrement, affiche les 50 livres suivants.

Pour faciliter le traitement des données, on devrait ajouter dans la réponse le nombre total d'enregistrements ainsi que les valeurs de limit et offset.

Une autre technique est d'avoir un nombre d'enregistrement fixe par page et de seulement permettre à l'usager de choisir la page qu'il veut afficher. Exemple, on décide d'afficher 30 enregistrements par page, l'url suivant va afficher les enregistrement 61 à 90 :

  • /livres?page=3

On peut bien sur combiner les deux méthodes comme c'est souvent le cas dans les sites d'achats en lignes (On peut choisir la page et le nombre d'articles affichés par page).

Source