# Les codes de statut

Le code de statut est la première chose qu'un client regarde. Un bon code évite au client de devoir lire le body pour savoir si ça a marché.

<p class="callout warning">Une API qui répond toujours `200 OK` avec `{"error": true}` dans le body oblige chaque client à réinventer la gestion d'erreurs. Le code de statut est fait pour ça : utilisez-le.</p>

Les exemples ci-dessous concernent l'API d'une bibliothèque en ligne : des livres, des membres, des emprunts.

### 2xx - Succès

<table id="bkmrk-codequand-l%27utiliser"><thead><tr><th>Code</th><th>Quand l'utiliser</th><th>Exemple</th></tr></thead><tbody><tr><td>`200 OK`</td><td>Succès avec un body</td><td>`GET /v1/livres`</td></tr><tr><td>`201 Created`</td><td>Ressource créée. Ajouter le header `Location`</td><td>`POST /v1/emprunts`</td></tr><tr><td>`204 No Content`</td><td>Succès sans body</td><td>`DELETE /v1/emprunts/42`</td></tr></tbody></table>

### 3xx - Redirection

<table id="bkmrk-codequand-l%27utiliser-1"><thead><tr><th>Code</th><th>Quand l'utiliser</th></tr></thead><tbody><tr><td>`301 Moved Permanently`</td><td>La ressource a changé d'adresse définitivement</td></tr><tr><td>`304 Not Modified`</td><td>La version en cache du client est toujours bonne</td></tr></tbody></table>

### 4xx - Erreur du client

<table id="bkmrk-codequand-l%27utiliser-2"><thead><tr><th>Code</th><th>Quand l'utiliser</th><th>Exemple</th></tr></thead><tbody><tr><td>`400 Bad Request`</td><td>Requête mal formée</td><td>Un body qui n'est pas du JSON valide</td></tr><tr><td>`401 Unauthorized`</td><td>Pas authentifié, ou authentification invalide</td><td>`GET /v1/me` sans token</td></tr><tr><td>`403 Forbidden`</td><td>Authentifié, mais pas autorisé</td><td>Un membre qui veut supprimer un livre du catalogue</td></tr><tr><td>`404 Not Found`</td><td>La ressource n'existe pas</td><td>`GET /v1/livres/999999`</td></tr><tr><td>`405 Method Not Allowed`</td><td>Méthode non supportée sur cette URI. Ajouter le header `Allow`</td><td>`DELETE /v1/livres` (supprimer tout le catalogue)</td></tr><tr><td>`406 Not Acceptable`</td><td>Format demandé dans `Accept` indisponible</td><td>`Accept: image/png`</td></tr><tr><td>`409 Conflict`</td><td>Conflit avec l'état actuel de la ressource</td><td>Emprunter un livre déjà emprunté</td></tr><tr><td>`418 I'm a teapot`</td><td>Le serveur est une théière (RFC 2324, poisson d'avril de 1998)</td><td>Demander un café à une théière</td></tr><tr><td>`422 Unprocessable Content`</td><td>Requête bien formée mais données invalides</td><td>Une date de retour antérieure à la date d'emprunt</td></tr><tr><td>`429 Too Many Requests`</td><td>Trop de requêtes. Ajouter le header `Retry-After`</td><td>Un script qui interroge l'API en boucle</td></tr></tbody></table>

### 5xx - Erreur du serveur

<table id="bkmrk-codequand-l%27utiliser-3"><thead><tr><th>Code</th><th>Quand l'utiliser</th></tr></thead><tbody><tr><td>`500 Internal Server Error`</td><td>Bug côté serveur. Ne jamais le renvoyer volontairement</td></tr><tr><td>`502 Bad Gateway`</td><td>Un intermédiaire n'a pas obtenu de réponse valide du serveur</td></tr><tr><td>`503 Service Unavailable`</td><td>Serveur indisponible (maintenance, surcharge)</td></tr></tbody></table>

### Les pièges classiques

- **401 ou 403 ?** `401` : « je ne sais pas qui tu es ». `403` : « je sais qui tu es, et c'est non ».
- **400 ou 422 ?** `400` : je n'arrive pas à lire ta requête. `422` : je l'ai lue, mais son contenu n'est pas valide. FastAPI renvoie `422` par défaut pour les erreurs de validation.
- **404 ou 403 ?** Pour une ressource qui appartient à quelqu'un d'autre, répondre `404` évite de révéler qu'elle existe. On en reparle au chapitre 8.

<p class="callout info">La liste complète est sur [MDN](https://developer.mozilla.org/fr/docs/Web/HTTP/Status). Et pour les retenir : [http.cat](https://http.cat).</p>