Yasin Avci

Yasin Avci

Développeur Full-Stack

Paris, France

Me contacter
Retour aux articles
APIBackendArchitecture

Concevoir une API REST qui vieillit bien

Versioning, gestion d'erreurs, pagination... Les conventions qui font la différence entre une API maintenable et un cauchemar technique.

10 janvier 20244 min de lecture

Une API mal conçue, c'est de la dette technique qui s'accumule à chaque nouveau client. Voici les principes que j'applique pour créer des APIs qui restent maintenables après des années d'évolution.

Nommer les endpoints : la clarté avant tout

Les ressources, pas les actions

❌ GET /getUsers
❌ POST /createUser
❌ PUT /updateUser/123

✅ GET /users
✅ POST /users
✅ PUT /users/123

L'URL décrit la ressource, le verbe HTTP décrit l'action.

Pluriel et cohérence

Choisissez une convention et tenez-vous-y :

✅ /users, /products, /orders
❌ /user, /products, /order (incohérent)

Relations imbriquées avec modération

✅ GET /users/123/orders (les commandes d'un utilisateur)
❌ GET /users/123/orders/456/items/789/details (trop profond)

Au-delà de 2 niveaux, préférez des endpoints séparés avec des filtres.

Gestion des erreurs : être explicite

Codes HTTP appropriés

| Code | Usage | |------|-------| | 200 | Succès | | 201 | Ressource créée | | 400 | Erreur de validation | | 401 | Non authentifié | | 403 | Non autorisé | | 404 | Ressource non trouvée | | 500 | Erreur serveur |

Format d'erreur standardisé

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Les données fournies sont invalides",
    "details": [
      {
        "field": "email",
        "message": "Format d'email invalide"
      }
    ]
  }
}

Toujours le même format, toujours le même niveau de détail. Le client sait à quoi s'attendre.

Pagination : ne jamais retourner tout

Le pattern offset/limit classique

GET /users?offset=0&limit=20

Simple, mais problématique sur les grandes tables (performance dégradée au fur et à mesure).

Le cursor-based pour les gros volumes

GET /users?cursor=abc123&limit=20

Le curseur encode la position dans la liste. Plus performant, mais plus complexe à implémenter.

La réponse paginée

{
  "data": [...],
  "pagination": {
    "total": 1234,
    "limit": 20,
    "offset": 0,
    "hasMore": true
  }
}

Versioning : anticiper le changement

Dans l'URL (recommandé)

GET /v1/users
GET /v2/users

Clair, explicite, facile à router.

Dans les headers

GET /users
Accept: application/vnd.api+json; version=2

Plus "RESTful" en théorie, mais moins pratique au quotidien.

Règle d'or

  • Les ajouts de champs sont rétrocompatibles
  • Les suppressions/modifications de champs nécessitent une nouvelle version
  • Maintenir maximum 2 versions en parallèle

Authentification : JWT avec prudence

Le flow classique

  1. Le client POST ses credentials sur /auth/login
  2. L'API retourne un JWT
  3. Le client envoie le JWT dans le header Authorization: Bearer xxx

Les pièges à éviter

❌ Stocker des données sensibles dans le JWT (visible côté client)
❌ Tokens qui n'expirent jamais
❌ Pas de mécanisme de révocation

✅ Payload minimal (user_id, rôles)
✅ Expiration courte (15min - 1h) + refresh token
✅ Blacklist des tokens révoqués

Documentation : l'investissement qui paie

OpenAPI (Swagger) minimum

paths:
  /users:
    get:
      summary: Liste des utilisateurs
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
      responses:
        '200':
          description: Liste paginée des utilisateurs

La doc générée automatiquement est toujours à jour.

Exemples concrets

Pour chaque endpoint, fournir :

  • Un exemple de requête
  • Un exemple de réponse succès
  • Un exemple de réponse erreur

Ce que j'aurais aimé savoir plus tôt

  1. Commencer simple — n'ajoutez pas de fonctionnalités "au cas où"
  2. Valider les entrées agressivement — une API trop permissive est un cauchemar à maintenir
  3. Logger tout — vous en aurez besoin pour débugger en prod
  4. Tester avec des clients réels — les tests unitaires ne suffisent pas

Une bonne API est invisible. Le client l'utilise sans se poser de questions, et vous la maintenez sans avoir peur de tout casser.