Tous les articles
APIBackendIngénierieArchitecture

Le guide de conception d'API : construire des interfaces qui durent dix ans

Jean-Eudes ASSOGBA12 octobre 20254 min de lecture
Le guide de conception d'API : construire des interfaces qui durent dix ans

Le guide de conception d'API : construire des interfaces qui durent dix ans

J'ai un jour hérité d'un codebase où le endpoint pour récupérer le profil d'un utilisateur était POST /api/getData. Il acceptait un corps JSON avec un champ type qui pouvait être « user », « profile », « account » ou « userProfile » — chacun retournant des formes légèrement différentes des mêmes données. Pas de documentation. Le format de réponse changeait selon qu'on passait un id en string ou en number.

Cette API avait deux ans et était déjà inmaintenable.

Votre API est l'interface la plus importante de votre logiciel — plus importante que l'UI, parce que l'UI peut changer sans casser les consommateurs. Une API, une fois publiée et adoptée, devient un contrat. Et les contrats sont douloureux à modifier.

REST n'est pas juste des URLs et du JSON

Permettez-moi de dire quelque chose qui va agacer certains : la plupart des APIs décrites comme « RESTful » ne le sont pas. Ce sont du JSON-sur-HTTP, ce qui est correct, mais elles ratent les principes qui font fonctionner REST à grande échelle.

Les ressources, pas les actions. Les URLs doivent identifier des choses, pas effectuer des opérations. /users/42 est une ressource. /getUser?id=42 est un appel RPC déguisé en URL.

Les méthodes HTTP portent du sens. GET lit. POST crée. PUT remplace. PATCH met à jour partiellement. DELETE supprime.

Les codes de statut communiquent l'intention. 200 signifie succès. 201 signifie créé. 404 signifie introuvable. 422 signifie données invalides. 500 signifie que vous avez fait une erreur.

# Bon
GET    /api/v1/projects           → Lister les projets
POST   /api/v1/projects           → Créer un projet
GET    /api/v1/projects/42        → Obtenir le projet 42
PATCH  /api/v1/projects/42        → Mettre à jour le projet 42
DELETE /api/v1/projects/42        → Supprimer le projet 42

# Mauvais
POST   /api/getProjects
POST   /api/createProject
POST   /api/updateProject
POST   /api/deleteProject

Le versioning : la décision qu'on ne peut pas reporter

Vous allez devoir faire des changements cassants. Acceptez-le maintenant et construisez pour ça dès le premier jour.

Je préfère le versioning par URL (/api/v1/, /api/v2/) au versioning par header. Oui, le versioning par URL est techniquement « moins RESTful ». Mais c'est explicite, visible dans les logs, facile à router, et impossible de se tromper.

La vraie discipline n'est pas le choix d'un schéma de versioning — c'est de définir ce qui constitue un changement cassant :

Changements cassants (nouvelle version requise) :

  • Supprimer un champ d'une réponse
  • Changer le type d'un champ
  • Rendre obligatoire un paramètre auparavant optionnel

Changements non cassants (même version) :

  • Ajouter un nouveau champ à une réponse
  • Ajouter un nouveau paramètre optionnel
  • Ajouter un nouveau endpoint

La pagination n'est pas optionnelle

Tout endpoint qui retourne une liste retournera éventuellement une liste trop grande pour une seule réponse. Construisez la pagination dès le premier jour.

Incluez toujours les métadonnées de pagination dans la réponse :

{
  "data": [...],
  "pagination": {
    "total": 247,
    "page": 3,
    "limit": 20,
    "hasMore": true
  }
}

Les réponses d'erreur méritent du soin

Je juge la qualité d'une API à la façon dont elle gère les erreurs. Une réponse d'erreur réfléchie dit au consommateur exactement ce qui a mal tourné, où, et idéalement comment le corriger.

{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Le corps de la requête contient des champs invalides.",
    "details": [
      {
        "field": "email",
        "message": "Doit être une adresse email valide.",
        "received": "not-an-email"
      }
    ]
  }
}

Comparez ça à { "error": "Bad request" }. Les deux retournent 400. L'un est cruel, l'autre est bienveillant.

Le rate limiting : protégez-vous poliment

Chaque API publique a besoin de rate limiting. Pas éventuellement — dès le lancement. Un seul client mal configuré peut faire tomber votre infrastructure.

Quand un client dépasse la limite, retournez 429 Too Many Requests avec un header Retry-After. Ne supprimez pas silencieusement les requêtes et ne retournez pas 500.

Documentez tout (mais écrivez pour des humains)

La documentation auto-générée depuis votre code n'est que le point de départ.

Une excellente documentation d'API inclut :

  • Guide de démarrage rapide : « Voici comment faire votre première requête en 5 minutes »
  • Guide d'authentification : Étape par étape, avec des exemples réels
  • Workflows courants : « Voici comment créer un projet et y ajouter des utilisateurs »
  • Guide de gestion des erreurs : « Quand vous voyez l'erreur X, voici quoi faire »
  • Exemples de code : Dans au moins 3 langages (cURL, JavaScript, Python)

La check-list

Avant de livrer tout endpoint d'API, vérifiez :

  • L'URL identifie une ressource (nom), pas une action (verbe)
  • La méthode HTTP correspond à l'opération
  • La réponse inclut le code de statut approprié
  • La pagination est implémentée pour les endpoints de liste
  • Les réponses d'erreur incluent code, message et détails
  • Le rate limiting est en place
  • L'authentification est requise et documentée
  • C'est versionné dans l'URL
  • Le format de réponse est cohérent avec tous les autres endpoints
  • Il a au moins un test d'intégration

Construisez des APIs comme si vous construisiez pour le développeur qui héritera de votre projet dans trois ans. Parce que ce développeur pourrait être vous.