04 - Les méthodes HTTP
Ce que tu vas apprendre
- Les 9 méthodes HTTP standardisees et leur semantique exacte
- La différence entre safe, idempotent et cacheable
- Les usages réels de HEAD, OPTIONS, TRACE et CONNECT
- Pourquoi TRACE est un risque de sécurité
- Les erreurs classiques dans l'utilisation des méthodes
Prerequisites
Avoir lu 02 - La requête HTTP et 03 - La réponse HTTP pour comprendre la structure des messages.
J'ai travaille sur un projet ou toutes les routes API etaient en POST. Creer un utilisateur ? POST. Lire un utilisateur ? POST. Supprimer un utilisateur ? POST. Le dev avait une justification : "POST, ca marche pour tout, pourquoi s'embeter avec le reste ?" La réponse courte : parce que les méthodes HTTP ont une semantique et que cette semantique est exploitee par les navigateurs, les caches, les proxies et les CDN.
Les 9 méthodes
Voici les neuf méthodes définies par la spec HTTP :
GET - Recuperer une ressource
HEAD - Comme GET mais sans le body
POST - Soumettre des donnees, creer une ressource
PUT - Remplacer une ressource
DELETE - Supprimer une ressource
PATCH - Modifier partiellement une ressource
OPTIONS - Decouvrir les capacites du serveur
TRACE - Echo de la requete (debug)
CONNECT - Etablir un tunnel TCP
Safe, idempotent, cacheable
Trois propriétés definissent le comportement attendu de chaque méthode :
| Méthode | Safe | Idempotent | Cacheable |
|---|---|---|---|
| GET | oui | oui | oui |
| HEAD | oui | oui | oui |
| POST | non | non | rarement |
| PUT | non | oui | non |
| DELETE | non | oui | non |
| PATCH | non | non | non |
| OPTIONS | oui | oui | non |
| TRACE | oui | oui | non |
| CONNECT | non | non | non |
Safe : la méthode ne modifie pas l'état du serveur. Un GET ne devrait jamais créer, modifier ou supprimer quoi que ce soit. Si ton GET /api/users/42 supprime l'utilisateur 42, tu as un problème.
Idempotent : appeler la méthode une fois ou dix fois produit le meme résultat. DELETE /api/users/42 appele deux fois devrait avoir le meme effet (l'utilisateur est supprime). Le deuxieme appel peut retourner 404, mais l'état du serveur ne change pas.
Cacheable : la réponse peut etre stockee et reutilisee. Seuls GET et HEAD sont cacheables par défaut. POST peut l'etre si le serveur envoie les bons headers, mais c'est rare.
GET : la méthode reine
GET /api/users?role=admin HTTP/1.1
Host: api.example.com
Accept: application/json
GET récupéré une ressource. Pas de body dans la requête (techniquement la spec ne l'interdit pas, mais en pratique personne ne le supporte). Les paramètres passent dans l'URL.
Ce qui va mal avec GET en pratique :
- Des GET qui modifient des donnees (compteurs de vues implementes en GET sans cache)
- Des GET avec des bodies (Elasticsearch le faisait, et ca a cause des problèmes avec les proxies)
- Des query strings trop longues (la limite depend du serveur, nginx coupe a 8 KB par défaut)
HEAD : GET sans le body
HEAD /api/users/42 HTTP/1.1
Host: api.example.com
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 234
Last-Modified: Sat, 29 Mar 2026 08:00:00 GMT
HEAD retourne exactement les memes headers qu'un GET, mais sans le body. Utilisation réelle :
- Verifier si une ressource existe (sans telecharger le contenu)
- Récupérer la taille d'un fichier avant de le telecharger (
Content-Length) - Verifier la fraicheur d'un cache (
Last-Modified,ETag) - Monitorer la disponibilité d'un endpoint (health checks legers)
POST : le couteau suisse
POST /api/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Content-Length: 45
{"name": "Charlie", "email": "c@example.com"}
POST soumet des donnees au serveur. La spec dit que POST peut faire a peu pres n'importe quoi, ce qui en fait la méthode la plus flexible mais aussi la plus abusee.
En pratique :
- Creer une ressource (le serveur choisit l'identifiant)
- Soumettre un formulaire
- Declencher un traitement (envoyer un email, lancer un job)
- Tout ce qui ne rentre pas dans les autres méthodes
POST n'est pas idempotent. Envoyer deux fois le meme POST peut créer deux ressources. C'est pour ca qu'on voit des patterns comme les tokens d'idempotence dans les API de paiement.
PUT : remplacement total
PUT /api/users/42 HTTP/1.1
Host: api.example.com
Content-Type: application/json
Content-Length: 52
{"name": "Charlie", "email": "c@example.com", "role": "admin"}
PUT remplace la ressource complète. Si tu omets un champ, il disparaît. C'est la différence fondamentale avec PATCH.
PUT est idempotent : envoyer le meme PUT dix fois produit le meme résultat. La ressource a le contenu que tu as envoye, point.
DELETE : supprimer
DELETE /api/users/42 HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOi...
HTTP/1.1 204 No Content
DELETE supprime la ressource. Idempotent : supprimer une ressource deja supprimee ne change rien (meme si le serveur retourne 404 au lieu de 204).
Est-ce que DELETE peut avoir un body ? La spec dit que le body n'a pas de semantique définie pour DELETE. Certains serveurs l'ignorent, d'autres le rejettent. Mon conseil : ne mets pas de body dans un DELETE.
PATCH : modification partielle
PATCH /api/users/42 HTTP/1.1
Host: api.example.com
Content-Type: application/json
Content-Length: 22
{"role": "moderator"}
PATCH modifie une partie de la ressource. Seuls les champs envoyes sont modifies, les autres restent intacts. C'est la méthode la plus utilisee en pratique pour les mises à jour, meme si PUT est conceptuellement plus propre.
PATCH n'est pas idempotent par définition. Imagine un PATCH qui incremente un compteur : l'appeler deux fois donne un résultat différent. En pratique, la plupart des PATCH "set field to value" sont idempotents, mais la spec ne le garantit pas.
OPTIONS : qu'est-ce que tu sais faire ?
OPTIONS /api/users HTTP/1.1
Host: api.example.com
Origin: https://frontend.example.com
HTTP/1.1 204 No Content
Allow: GET, POST, OPTIONS
Access-Control-Allow-Origin: https://frontend.example.com
Access-Control-Allow-Methods: GET, POST, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
OPTIONS a deux usages :
- Découverte : le header
Allowliste les méthodes supportees par la ressource - CORS preflight : le navigateur envoie automatiquement un OPTIONS avant certaines requêtes cross-origin pour vérifier les permissions
Le CORS preflight est de loin l'usage le plus courant. Si tu vois des requêtes OPTIONS dans tes logs et que tu ne les as pas envoyees, c'est le navigateur qui vérifié les permissions CORS.
TRACE : le piège
TRACE /api/users HTTP/1.1
Host: api.example.com
Cookie: session=abc123
HTTP/1.1 200 OK
Content-Type: message/http
TRACE /api/users HTTP/1.1
Host: api.example.com
Cookie: session=abc123
TRACE renvoie la requête telle que le serveur l'a reçue. L'idee originale : debugger les proxies intermediaires en voyant comment ils modifient les headers.
Le problème : un attaquant peut utiliser TRACE pour voler des cookies HttpOnly via du JavaScript (attaque Cross-Site Tracing). Le script envoie un TRACE, la réponse contient les cookies, et le script les lit meme s'ils sont HttpOnly.
La bonne pratique : désactivé TRACE sur tous tes serveurs. Nginx le bloque par défaut. Apache aussi depuis des annees.
CONNECT : le tunnel
CONNECT api.example.com:443 HTTP/1.1
Host: api.example.com
HTTP/1.1 200 Connection Established
CONNECT transforme la connexion HTTP en tunnel TCP brut. C'est utilise par les proxies HTTP pour permettre les connexions HTTPS. Le client dit au proxy "connecte-moi a ce serveur sur ce port", et le proxy relaie les octets sans les lire.
Tu ne feras probablement jamais un CONNECT toi-meme. C'est le navigateur ou le client HTTP qui l'utilise automatiquement quand tu passes par un proxy HTTP pour acceder a un site HTTPS.
Les erreurs classiques
Tout en POST : on perd le caching, l'idempotence, et la semantique. Les CDN ne cachent pas les POST. Les navigateurs ne peuvent pas rejouer un POST sans demander confirmation.
DELETE avec confirmation dans le body : "envoie {"confirm": true} pour vraiment supprimer." C'est un anti-pattern. Si tu as besoin de confirmation, utilise un workflow en deux étapes (POST pour demander la suppression, puis DELETE pour confirmer).
PATCH qui remplace tout : si ton PATCH attend tous les champs de la ressource, c'est un PUT deguise. Utilise PUT et sois honnete.
Sur paltemps.fr, on suit une regle simple : si la méthode ne correspond pas a la semantique, on ne l'utilise pas, meme si "ca marche quand meme."
Résumé
- 9 méthodes HTTP, chacune avec une semantique precise
- Safe = pas de modification, Idempotent = repetable sans effet, Cacheable = stockable
- GET et HEAD sont les seules méthodes cacheables par défaut
- PATCH pour les mises à jour partielles, PUT pour le remplacement complet
- OPTIONS est surtout utilise pour les preflight CORS
- Desactive TRACE sur tous tes serveurs
Precedent : 03 - La réponse HTTP Suivant : 05 - Les codes de statut