alltools.one
API‱
2025-06-30
‱
9 min
‱
alltools.one Team
JSONAPIRESTDesign PatternsBackend

Patterns de conception d'API JSON : construire de meilleures API REST

Une API bien conçue est un plaisir à utiliser. Une API mal conçue crée des bugs, de la frustration et de la dette technique. Ce guide couvre des patterns éprouvés pour concevoir des API REST JSON qui sont cohérentes, découvrables et maintenables.

Nommage des ressources

Les ressources sont des noms, pas des verbes. Utilisez des noms au pluriel pour les collections et des ressources individuelles via ID :

GET    /api/users          # Lister les utilisateurs
POST   /api/users          # Créer un utilisateur
GET    /api/users/123      # Obtenir l'utilisateur 123
PUT    /api/users/123      # Mettre Ă  jour l'utilisateur 123
DELETE /api/users/123      # Supprimer l'utilisateur 123

Conventions de nommage :

  • Utilisez des minuscules avec des tirets : /api/blog-posts (pas blogPosts ni blog_posts)
  • Imbriquez les ressources liĂ©es : /api/users/123/orders
  • Limitez l'imbrication Ă  2 niveaux : /api/users/123/orders/456 (pas plus profond)
  • Évitez les verbes dans les URL : /api/users/123/activate est acceptable pour les actions qui ne correspondent pas au CRUD

Enveloppe de réponse

Encapsulez les réponses dans une enveloppe cohérente :

{
  "data": {
    "id": "123",
    "type": "user",
    "attributes": {
      "name": "Alice",
      "email": "alice@example.com",
      "createdAt": "2024-01-15T10:30:00Z"
    }
  },
  "meta": {
    "requestId": "req_abc123"
  }
}

Pour les collections :

{
  "data": [
    { "id": "123", "name": "Alice" },
    { "id": "456", "name": "Bob" }
  ],
  "meta": {
    "total": 142,
    "page": 1,
    "perPage": 20
  }
}

Validez vos réponses API avec notre Validateur JSON pour vous assurer qu'elles correspondent à votre schéma.

Pagination

Trois approches courantes :

Basée sur l'offset (la plus simple)

GET /api/users?page=2&per_page=20
{
  "data": [...],
  "meta": {
    "page": 2,
    "perPage": 20,
    "total": 142,
    "totalPages": 8
  }
}

Avantage : Simple, permet de sauter à n'importe quelle page. Inconvénient : Résultats incohérents avec des insertions/suppressions simultanées.

Basée sur le curseur (la plus fiable)

GET /api/users?cursor=eyJpZCI6MTIzfQ&limit=20
{
  "data": [...],
  "meta": {
    "hasNext": true,
    "nextCursor": "eyJpZCI6MTQzfQ"
  }
}

Avantage : Cohérente avec les modifications simultanées, performante sur les grands ensembles de données. Inconvénient : Impossible de sauter à des pages arbitraires.

Basée sur les clés (la plus performante)

GET /api/users?after_id=123&limit=20

Utilise l'ID du dernier élément (ou un autre champ trié) pour récupérer la page suivante. Similaire à la pagination par curseur mais avec des paramÚtres transparents.

Recommandation : Utilisez la pagination par curseur pour les flux en temps rĂ©el et les grands ensembles de donnĂ©es. Utilisez la pagination par offset pour les tableaux de bord d'administration oĂč la navigation par page compte.

Filtrage et tri

Filtrage

GET /api/users?status=active&role=admin
GET /api/users?created_after=2024-01-01
GET /api/users?search=alice

Pour les filtres complexes, envisagez un paramĂštre de requĂȘte dĂ©diĂ© :

GET /api/users?filter[status]=active&filter[role]=admin

Tri

GET /api/users?sort=name          # Ascendant
GET /api/users?sort=-created_at   # Descendant (préfixe avec -)
GET /api/users?sort=-created_at,name  # Champs multiples

Gestion des erreurs

Des réponses d'erreur cohérentes sont critiques pour l'utilisabilité de l'API :

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "details": [
      {
        "field": "email",
        "message": "Must be a valid email address",
        "value": "not-an-email"
      },
      {
        "field": "age",
        "message": "Must be between 0 and 150",
        "value": -5
      }
    ]
  },
  "meta": {
    "requestId": "req_abc123"
  }
}

Codes de statut HTTP Ă  utiliser :

CodeSignificationQuand
200OKGET, PUT réussis
201CreatedPOST réussi
204No ContentDELETE réussi
400Bad RequestErreurs de validation
401UnauthorizedAuth manquante/invalide
403ForbiddenAuth valide, permissions insuffisantes
404Not FoundLa ressource n'existe pas
409ConflictRessource dupliquée, conflit de version
422UnprocessableSémantiquement invalide
429Too Many RequestsLimite de débit dépassée
500Internal ErrorErreur serveur inattendue

Versionnage

Trois approches :

Chemin d'URL (recommandé)

GET /api/v1/users
GET /api/v2/users

Avantage : Explicite, facile Ă  router, facile Ă  tester.

Basé sur les headers

GET /api/users
Accept: application/vnd.myapi.v2+json

Avantage : URL propres. Inconvénient : Plus difficile à tester, moins découvrable.

ParamĂštre de requĂȘte

GET /api/users?version=2

Avantage : Facile à tester. Inconvénient : Sémantique de paramÚtre optionnel.

Recommandation : Le versionnage par chemin d'URL est le choix le plus pratique. C'est explicite, cacheable et fonctionne avec tous les outils HTTP.

Gestion des dates et heures

Utilisez toujours ISO 8601 en UTC :

{
  "createdAt": "2024-01-15T10:30:00Z",
  "updatedAt": "2024-01-15T14:22:33Z",
  "expiresAt": "2024-12-31T23:59:59Z"
}

N'utilisez jamais les timestamps Unix dans les rĂ©ponses API — ils sont ambigus (secondes vs millisecondes) et non lisibles par l'humain. Pour en savoir plus sur la gestion des timestamps, consultez notre guide des timestamps Unix.

Limitation de débit

Communiquez les limites de débit dans les headers de réponse :

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 67
X-RateLimit-Reset: 1705312800
Retry-After: 30

Renvoyez 429 Too Many Requests quand la limite est dépassée, avec un message d'erreur clair et un header Retry-After.

HATEOAS (optionnel mais puissant)

Incluez des liens vers les ressources et actions liées :

{
  "data": {
    "id": "123",
    "name": "Alice",
    "links": {
      "self": "/api/users/123",
      "orders": "/api/users/123/orders",
      "avatar": "/api/users/123/avatar"
    }
  }
}

Cela rend votre API auto-documentée et réduit la construction d'URL cÎté client.

FAQ

Dois-je utiliser la spécification JSON:API ou concevoir mon propre format ?

La spĂ©cification JSON:API (jsonapi.org) fournit un standard complet, mais elle peut ĂȘtre verbeuse pour les API simples. Pour la plupart des projets, concevoir un format personnalisĂ© plus simple en suivant les patterns de ce guide est plus pratique. Utilisez JSON:API si vous avez besoin de bibliothĂšques clientes automatiques et d'un standard strict.

Comment gérer les mises à jour partielles (PATCH vs PUT) ?

Utilisez PUT pour le remplacement complet de la ressource (le client envoie tous les champs). Utilisez PATCH pour les mises à jour partielles (le client n'envoie que les champs modifiés). PATCH avec JSON Merge Patch (RFC 7396) est l'approche la plus simple : envoyez un objet JSON avec uniquement les champs à mettre à jour, et null pour supprimer un champ.

Ressources connexes

Published on 2025-06-30
JSON API Design Patterns: Building Better REST APIs | alltools.one