📬 Méthodes HTTP
📖 Définition
Les méthodes HTTP indiquent l'action que le client souhaite effectuer sur le serveur. Chaque méthode a une signification et un usage spécifiques, et constitue le cœur de la conception d'API RESTful.
🎯 Comprendre par une analogie
Système de bibliothèque
GET = Rechercher un livre (lecture)
├─ Demander au bibliothécaire "Avez-vous ce livre ?"
├─ Ne récupère que des données
└─ Aucun changement dans l'état de la bibliothèque
POST = Enregistrer un nouveau livre (création)
├─ Ajouter un nouveau livre à la bibliothèque
├─ Modification de l'état de la bibliothèque
└─ Création d'une nouvelle ressource
PUT = Remplacer entièrement les informations d'un livre (mise à jour complète)
├─ Réécrire toutes les informations du livre
└─ Remplacement total
PATCH = Modifier partiellement les informations d'un livre (mise à jour partielle)
├─ Modifier uniquement certaines informations du livre (ex : disponibilité)
└─ Modification partielle
DELETE = Supprimer un livre (suppression)
├─ Retirer le livre de la bibliothèque
└─ Suppression de la ressource
💡 Méthodes HTTP principales
GET - Récupération de données
Usage : Récupérer une ressource du serveur
Caractéristiques :
├─ Sûre (Safe) : Ne modifie pas l'état du serveur
├─ Idempotente : Résultat identique lors de plusieurs appels
├─ Peut être mise en cache
└─ Apparaît dans l'historique du navigateur
Exemple de requête :
GET /api/users HTTP/1.1
Host: example.com
// API Fetch de JavaScript
fetch('https://api.example.com/users')
.then(response => response.json())
.then(data => console.log(data));
// jQuery
$.get('https://api.example.com/users', function(data) {
console.log(data);
});
// axios
axios.get('https://api.example.com/users')
.then(response => console.log(response.data));
# curl
curl https://api.example.com/users
# Récupération d'un utilisateur spécifique
curl https://api.example.com/users/123
# Utilisation de paramètres de requête
curl "https://api.example.com/users?page=1&limit=10"
Exemple de réponse :
HTTP/1.1 200 OK
Content-Type: application/json
{
"users": [
{ "id": 1, "name": "Jean Dupont" },
{ "id": 2, "name": "Marie Martin" }
]
}
POST - Création de données
Usage : Créer une nouvelle ressource sur le serveur
Caractéristiques :
├─ Non sûre : Modifie l'état du serveur
├─ Non idempotente : Plusieurs appels créent plusieurs ressources
├─ Non cachable
└─ Inclut des données dans le corps de la requête
Exemple de requête :
POST /api/users HTTP/1.1
Host: example.com
Content-Type: application/json
{
"name": "Jean Dupont",
"email": "jean@example.com"
}
// Fetch API
fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Jean Dupont',
email: 'jean@example.com'
})
})
.then(response => response.json())
.then(data => console.log(data));
// axios
axios.post('https://api.example.com/users', {
name: 'Jean Dupont',
email: 'jean@example.com'
})
.then(response => console.log(response.data));
# curl
curl -X POST https://api.example.com/users \
-H "Content-Type: application/json" \
-d '{"name":"Jean Dupont","email":"jean@example.com"}'
Exemple de réponse :
HTTP/1.1 201 Created
Location: /api/users/123
Content-Type: application/json
{
"id": 123,
"name": "Jean Dupont",
"email": "jean@example.com",
"createdAt": "2025-01-26T10:00:00Z"
}
PUT - Mise à jour complète des données
Usage : Remplacer une ressource entière par de nouvelles données
Caractéristiques :
├─ Non sûre : Modifie l'état du serveur
├─ Idempotente : Résultat identique lors de plusieurs appels
├─ Remplace entièrement la ressource
└─ Peut créer si la ressource n'existe pas
Exemple de requête :
PUT /api/users/123 HTTP/1.1
Host: example.com
Content-Type: application/json
{
"name": "Jean Dupont",
"email": "nouveau-email@example.com",
"phone": "01 23 45 67 89"
}
// Fetch API
fetch('https://api.example.com/users/123', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Jean Dupont',
email: 'nouveau-email@example.com',
phone: '01 23 45 67 89'
})
})
.then(response => response.json())
.then(data => console.log(data));
// axios
axios.put('https://api.example.com/users/123', {
name: 'Jean Dupont',
email: 'nouveau-email@example.com',
phone: '01 23 45 67 89'
})
.then(response => console.log(response.data));
# curl
curl -X PUT https://api.example.com/users/123 \
-H "Content-Type: application/json" \
-d '{"name":"Jean Dupont","email":"nouveau-email@example.com","phone":"01 23 45 67 89"}'
PATCH - Mise à jour partielle des données
Usage : Modifier uniquement une partie des données d'une ressource
Caractéristiques :
├─ Non sûre : Modifie l'état du serveur
├─ Peut être idempotente ou non
├─ Modifie uniquement certains champs
└─ Plus efficace que PUT
Exemple de requête :
PATCH /api/users/123 HTTP/1.1
Host: example.com
Content-Type: application/json
{
"email": "nouveau-email@example.com"
}
// Fetch API
fetch('https://api.example.com/users/123', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: 'nouveau-email@example.com'
})
})
.then(response => response.json())
.then(data => console.log(data));
// axios
axios.patch('https://api.example.com/users/123', {
email: 'nouveau-email@example.com'
})
.then(response => console.log(response.data));
# curl
curl -X PATCH https://api.example.com/users/123 \
-H "Content-Type: application/json" \
-d '{"email":"nouveau-email@example.com"}'
Comparaison PUT vs PATCH :
Données existantes :
{
"id": 123,
"name": "Jean Dupont",
"email": "ancien@example.com",
"phone": "01 11 22 33 44"
}
Requête PUT (remplacement total) :
{
"name": "Jean Dupont",
"email": "nouveau@example.com"
}
Résultat :
{
"id": 123,
"name": "Jean Dupont",
"email": "nouveau@example.com"
// Champ téléphone supprimé !
}
Requête PATCH (modification partielle) :
{
"email": "nouveau@example.com"
}
Résultat :
{
"id": 123,
"name": "Jean Dupont",
"email": "nouveau@example.com",
"phone": "01 11 22 33 44"
// Champ téléphone conservé !
}
DELETE - Suppression de données
Usage : Supprimer une ressource
Caractéristiques :
├─ Non sûre : Modifie l'état du serveur
├─ Idempotente : Plusieurs appels donnent le même résultat
├─ Corps de réponse potentiellement vide
└─ Suppression potentiellement irréversible
Exemple de requête :
DELETE /api/users/123 HTTP/1.1
Host: example.com
// Fetch API
fetch('https://api.example.com/users/123', {
method: 'DELETE'
})
.then(response => {
if (response.ok) {
console.log('Suppression effectuée');
}
});
// axios
axios.delete('https://api.example.com/users/123')
.then(response => console.log('Suppression effectuée'));
# curl
curl -X DELETE https://api.example.com/users/123
Exemple de réponse :
HTTP/1.1 204 No Content
ou
HTTP/1.1 200 OK
Content-Type: application/json
{
"message": "Utilisateur supprimé",
"deletedId": 123
}
🔍 Autres méthodes HTTP
HEAD - Récupération uniquement des en-têtes
Usage : Identique à GET mais ne retourne que les en-têtes sans corps
Cas d'utilisation :
├─ Vérifier l'existence d'une ressource
├─ Vérifier la taille du fichier
└─ Vérifier le temps de modification
Exemple :
HEAD /api/users/123 HTTP/1.1
Host: example.com
Réponse :
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 256
Last-Modified: Sat, 26 Jan 2025 10:00:00 GMT
# curl
curl -I https://api.example.com/users/123
OPTIONS - Vérification des méthodes supportées
Usage : Vérifier les méthodes supportées par le serveur (utilisé pour les requêtes préliminaires CORS)
Exemple :
OPTIONS /api/users HTTP/1.1
Host: example.com
Réponse :
HTTP/1.1 200 OK
Allow: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Origin: *
# curl
curl -X OPTIONS https://api.example.com/users -i
📊 Comparaison des attributs des méthodes
┌─────────┬──────┬────────┬─────────┬────────────┐
│ Méthode │ Sûre │ Idempotence │ Cachable │ Corps requête │
├─────────┼──────┼────────┼─────────┼────────────┤
│ GET │ ✅ │ ✅ │ ✅ │ ❌ │
│ POST │ ❌ │ ❌ │ ❌ │ ✅ │
│ PUT │ ❌ │ ✅ │ ❌ │ ✅ │
│ PATCH │ ❌ │ △ │ ❌ │ ✅ │
│ DELETE │ ❌ │ ✅ │ ❌ │ △ │
│ HEAD │ ✅ │ ✅ │ ✅ │ ❌ │
│ OPTIONS │ ✅ │ ✅ │ ❌ │ ❌ │
└─────────┴── ────┴────────┴─────────┴────────────┘
Explication des termes :
- Sûre (Safe) : Ne modifie pas l'état du serveur
- Idempotente (Idempotent) : Résultat identique lors de plusieurs appels
- Cachable : Possibilité de mettre en cache la réponse
💡 Conception d'API RESTful
Mappage CRUD avec méthodes HTTP
Create → POST
Read → GET
Update → PUT / PATCH
Delete → DELETE
Exemple d'API RESTful
Ressource : utilisateurs (users)
GET /users - Liste tous les utilisateurs
GET /users/123 - Récupère un utilisateur spécifique
POST /users - Crée un nouvel utilisateur
PUT /users/123 - Remplace complètement un utilisateur
PATCH /users/123 - Modifie partiellement un utilisateur
DELETE /users/123 - Supprime un utilisateur
Ressources imbriquées :
GET /users/123/posts - Liste des posts d'un utilisateur
GET /users/123/posts/456 - Récupère un post spécifique
POST /users/123/posts - Crée un nouveau post
PUT /users/123/posts/456 - Modifie un post
DELETE /users/123/posts/456 - Supprime un post
Exemple pratique : API de blog
// API de posts de blog
// 1. Liste des posts (pagination, filtrage)
GET /api/posts?page=1&limit=10&category=tech
// 2. Récupération d'un post spécifique
GET /api/posts/123
// 3. Création d'un nouveau post
POST /api/posts
{
"title": "Maîtrise complète des méthodes HTTP",
"content": "...",
"category": "tech"
}
// 4. Mise à jour complète d'un post
PUT /api/posts/123
{
"title": "Maîtrise complète des méthodes HTTP (mis à jour)",
"content": "...",
"category": "tech"
}
// 5. Mise à jour partielle (augmentation du nombre de vues)
PATCH /api/posts/123
{
"views": 101
}
// 6. Suppression d'un post
DELETE /api/posts/123
// 7. Commentaires
GET /api/posts/123/comments - Liste des commentaires
POST /api/posts/123/comments - Création d'un commentaire
DELETE /api/posts/123/comments/456 - Suppression d'un commentaire
🤔 Questions fréquentes
Q1. Quelle est la différence entre POST et PUT ?
R :
POST :
├─ Crée une nouvelle ressource
├─ Le serveur détermine l'URI de la ressource
├─ Non idempotent (plusieurs appels créent plusieurs ressources)
└─ Exemple : POST /users
PUT :
├─ Remplace entièrement une ressource
├─ Le client spécifie l'URI de la ressource
├─ Idempotent (plusieurs appels donnent le même résultat)
└─ Exemple : PUT /users/123
Analogie pratique :
POST = "Créez un nouveau compte bancaire" (la banque attribue un numéro)
PUT = "Remplacez toutes les informations du compte 123"
Q2. Peut-on envoyer un corps de requête avec GET ?
R :
Techniquement possible mais :
├─ Autorisé par la spécification HTTP mais non recommandé
├─ Ignoré par de nombreux serveurs/frameworks
├─ Problèmes de mise en cache et de journalisation
└─ Utiliser des paramètres de requête recommandé
❌ Mauvais exemple :
GET /api/users
{
"filters": { "age": 25 }
}
✅ Bon exemple :
GET /api/users?age=25
Ou utiliser POST pour des recherches complexes :
POST /api/users/search
{
"filters": { "age": 25, "city": "Paris" }
}
Q3. Peut-on envoyer un corps avec DELETE ?
R :
Possible mais à utiliser avec précaution :
├─ Autorisé par la spécification HTTP
├─ Certains serveurs/proxys peuvent l'ignorer
├─ Généralement, l'ID de ressource est inclus dans l'URI
└─ Le corps peut transmettre des informations supplémentaires
Exemple d'utilisation :
✅ Méthode standard :
DELETE /api/users/123
✅ Conditions de suppression complexes :
DELETE /api/posts/bulk
{
"ids": [1, 2, 3, 4, 5]
}
✅ Transmission de la raison de suppression :
DELETE /api/users/123
{
"reason": "Demande de l'utilisateur",
"confirm": true
}
Q4. Pourquoi l'idempotence est-elle importante ?
R :
Importance de l'idempotence :
1. Réponse aux défaillances réseau
├─ Possibilité de réessayer en cas d'échec
├─ Pas d'inquiétude concernant les requêtes en double
└─ Reprise sûre
Exemples :
GET /users/123 → Plusieurs appels sûrs
POST /users → Plusieurs appels créent plusieurs utilisateurs !
PUT /users/123 → Plusieurs appels donnent le même résultat
DELETE /users/123 → Plusieurs suppressions donnent le même résultat
2. Logique de reprise côté client
├─ Réessais sûrs en cas de timeout
└─ Possibilité de mise en place de mécanismes de reprise automatique
3. Mise en cache et optimisation
├─ Requêtes idempotentes peuvent être mises en cache
└─ Optimisation de performance facilitée
Q5. Critères de sélection des méthodes en pratique ?
R :
Guide de sélection :
1. Lecture de données uniquement
→ GET
2. Création de nouvelles données
→ POST
3. Remplacement complet des données
→ PUT
Ex : Mise à jour complète du profil utilisateur
4. Modification partielle de données
→ PATCH
Ex : Incrémentation du nombre de likes, changement d'état
5. Suppression de données
→ DELETE
6. Recherche complexe
→ POST /search
(Contournement des limites de longueur d'URL de GET)
Exemples pratiques :
// ✅ Bon exemple
GET /api/products - Liste des produits
GET /api/products/123 - Détails du produit
POST /api/products - Enregistrement d'un produit
PATCH /api/products/123/stock - Modification du stock
PUT /api/products/123 - Mise à jour complète du produit
DELETE /api/products/123 - Suppression du produit
// ❌ Mauvais exemple
GET /api/deleteProduct?id=123 - Utiliser DELETE
POST /api/getProducts - Utiliser GET
POST /api/updateProduct - Utiliser PUT/PATCH
🎓 Mise en pratique
1. Pratique avec l'API Fetch
// Requête GET
async function getUser(id) {
const response = await fetch(`https://api.example.com/users/${id}`);
const data = await response.json();
return data;
}
// Requête POST
async function createUser(userData) {
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(userData)
});
return await response.json();
}
// Requête PUT
async function updateUser(id, userData) {
const response = await fetch(`https://api.example.com/users/${id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(userData)
});
return await response.json();
}
// Requête PATCH
async function patchUser(id, partialData) {
const response = await fetch(`https://api.example.com/users/${id}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(partialData)
});
return await response.json();
}
// Requête DELETE
async function deleteUser(id) {
const response = await fetch(`https://api.example.com/users/${id}`, {
method: 'DELETE'
});
return response.ok;
}
2. Gestion des erreurs
async function apiRequest(url, options = {}) {
try {
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(`Erreur HTTP ! statut : ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Échec de la requête API :', error);
throw error;
}
}
// Exemple d'utilisation
try {
const user = await apiRequest('https://api.example.com/users/123');
console.log(user);
} catch (error) {
console.error('Échec de la récupération de l\'utilisateur');
}
🔗 Documents associés
- Qu'est-ce que HTTP ? - Concepts de base de HTTP
- Codes de statut HTTP - Signification de 200, 404, 500
- En-têtes HTTP - En-têtes de requête/réponse
- Qu'est-ce qu'une API ? - Concepts de base des API
🎬 Conclusion
Les méthodes HTTP sont au cœur des API RESTful. Comprendre leurs caractéristiques vous permettra de concevoir des API intuitives et faciles à maintenir !
Prochaine étape : Lisez Codes de statut HTTP pour comprendre 200, 404, 500, etc.