Pourquoi Fetch API et requêtes HTTP ?
La Fetch API est une interface moderne pour effectuer des requêtes réseau en JavaScript, remplaçant les anciennes méthodes comme XMLHttpRequest. Elle offre un flux de travail plus simple, plus performant et plus flexible.
Un cas d'usage concret : Imaginez que vous ayez une application web qui affiche le temps actuel pour différentes villes. Vous pouvez utiliser la Fetch API pour récupérer les données météorologiques depuis une API tierce comme OpenWeatherMap.
Prerequis
- Connaissance de base de JavaScript
- Familiarité avec les concepts d'asynchronisme et de promesses en JavaScript
- Node.js installé (pour exécuter des exemples côté serveur)
# Installation de Node.js npm install -g node
Concepts fondamentaux
1. fetch()
La fonction fetch() prend une URL et retourne une promesse qui se résout en une réponse HTTP.
import fetch from 'node-fetch';
async function getWeather(city) {
const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=YOUR_API_KEY`);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
}
getWeather('Paris').then(data => console.log(data)).catch(error => console.error(error));
2. Méthodes HTTP
La Fetch API permet d'utiliser différents méthodes HTTP comme GET, POST, PUT, DELETE, etc.
async function createUser(username, email) {
const response = await fetch('https://jsonplaceholder.typicode.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ username, email })
});
return response.json();
}
createUser('john_doe', 'john@example.com').then(user => console.log(user)).catch(error => console.error(error));
3. Gestion des erreurs
Il est important de gérer les erreurs lors des requêtes réseau.
async function fetchUserData(userId) {
try {
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
} catch (error) {
console.error('There has been a problem with your fetch operation:', error);
}
}
fetchUserData(1).then(data => console.log(data)).catch(error => console.error(error));
4. Headers et corps de requête
Vous pouvez personnaliser les headers et le corps de votre requête.
async function createUserWithHeaders(username, email) {
const response = await fetch('https://jsonplaceholder.typicode.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_TOKEN'
},
body: JSON.stringify({ username, email })
});
return response.json();
}
createUserWithHeaders('john_doe', 'john@example.com').then(user => console.log(user)).catch(error => console.error(error));
Mise en pratique : Projet fil rouge
Mini-projet : Gestionnaire de tâches
Étape 1 : Création du projet
mkdir task-manager && cd task-manager
npm init -y
Étape 2 : Installation des dépendances
npm install express body-parser
Étape 3 : Création du fichier server.js
// Importer les modules nécessaires
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
let tasks = [];
// Route pour ajouter une tâche
app.post('/tasks', (req, res) => {
const task = { id: Date.now(), ...req.body };
tasks.push(task);
res.status(201).json(task);
});
// Route pour récupérer toutes les tâches
app.get('/tasks', (req, res) => {
res.json(tasks);
});
// Route pour mettre à jour une tâche
app.put('/tasks/:id', (req, res) => {
const taskId = parseInt(req.params.id);
const taskIndex = tasks.findIndex(t => t.id === taskId);
if (taskIndex !== -1) {
tasks[taskIndex] = { ...tasks[taskIndex], ...req.body };
res.json(tasks[taskIndex]);
} else {
res.status(404).json({ message: 'Task not found' });
}
});
// Route pour supprimer une tâche
app.delete('/tasks/:id', (req, res) => {
const taskId = parseInt(req.params.id);
tasks = tasks.filter(t => t.id !== taskId);
res.status(204).send();
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server is running on port ${PORT}`));
Étape 4 : Création du fichier client.js
// Importer les modules nécessaires
import fetch from 'node-fetch';
async function addTask(task) {
const response = await fetch('http://localhost:3000/tasks', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(task)
});
return response.json();
}
async function getTasks() {
const response = await fetch('http://localhost:3000/tasks');
return response.json();
}
async function updateTask(id, updatedTask) {
const response = await fetch(`http://localhost:3000/tasks/${id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(updatedTask)
});
return response.json();
}
async function deleteTask(id) {
const response = await fetch(`http://localhost:3000/tasks/${id}`, {
method: 'DELETE'
});
return response.status === 204;
}
// Exemple d'utilisation
addTask({ title: 'Faire les courses', completed: false })
.then(task => console.log('Task added:', task))
.catch(error => console.error(error));
getTasks()
.then(tasks => console.log('Tasks:', tasks))
.catch(error => console.error(error));
updateTask(1, { completed: true })
.then(updatedTask => console.log('Task updated:', updatedTask))
.catch(error => console.error(error));
deleteTask(1)
.then(deleted => console.log('Task deleted:', deleted))
.catch(error => console.error(error));
Étape 5 : Exécution du serveur et du client
node server.js
##
node client.js
Erreurs fréquentes et debugging
1. TypeError: Failed to fetch
Cela peut se produire si la requête est fausse ou que l'API n'est pas accessible.
fetch('https://nonexistentapi.com/data')
.then(response => response.json())
.catch(error => console.error(error));
##
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(response => response.json())
.catch(error => console.error(error));
2. SyntaxError: Unexpected token < in JSON at position 0
Cela signifie que la réponse n'est pas du JSON valide.
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(response => response.text()) // Utiliser text() au lieu de json()
.catch(error => console.error(error));
##
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(response => response.json())
.catch(error => console.error(error));
3. Fetch API not defined
Cela peut se produire si vous essayez d'utiliser Fetch API dans un environnement non supportant nativement cette API (comme certains navigateurs obsolètes).
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(response => response.json())
.catch(error => console.error(error));
##
import fetch from 'node-fetch';
Pour aller plus loin
1. Utiliser async/await
async/await rend le code plus lisible et plus facile à maintenir.
// Exemple avec async/await
async function getUser(userId) {
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
}
getUser(1).then(user => console.log(user)).catch(error => console.error(error));
2. Gérer les cookies
Vous pouvez gérer les cookies en utilisant l'option credentials dans la requête.
// Exemple avec gestion des cookies
fetch('https://example.com/data', {
method: 'GET',
credentials: 'include'
})
.then(response => response.json())
.catch(error => console.error(error));
3. Utiliser AbortController
Vous pouvez annuler une requête en utilisant AbortController.
// Exemple avec AbortController
const controller = new AbortController();
const signal = controller.signal;
fetch('https://jsonplaceholder.typicode.com/posts/1', { signal })
.then(response => response.json())
.catch(error => console.error(error));
// Annuler la requête après 500ms
setTimeout(() => controller.abort(), 500);
Défi pratique : Créer un CLI tool pour récupérer les données d'une API
- Créez un nouveau projet Node.js.
- Installez
commanderpour créer un CLI tool. - Utilisez la Fetch API pour récupérer des données depuis une API et les afficher en console.
mkdir api-cli && cd api-cli
npm init -y
##
npm install commander
Étape 4 : Création du fichier index.js
// Importer les modules nécessaires
const program = require('commander');
const fetch from 'node-fetch';
program
.option('-u, --url <url>', 'URL de l'API')
.parse(process.argv);
async function fetchData(url) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
} catch (error) {
console.error('There has been a problem with your fetch operation:', error);
}
}
program.on('option:url', async () => {
const url = program.url;
if (!url) {
console.log('Please provide a URL');
process.exit(1);
}
const data = await fetchData(url);
if (data) {
console.log(JSON.stringify(data, null, 2));
}
});
program.parse(process.argv);
Étape 5 : Exécution du CLI tool
node index.js --url https://jsonplaceholder.typicode.com/posts/1
Ce tutoriel vous a permis de comprendre les concepts fondamentaux de la Fetch API et d'effectuer des requêtes HTTP en JavaScript. Vous avez également appris à créer un mini-projet complet et à gérer les erreurs fréquentes lors des requêtes réseau. Enfin, vous avez découvert comment approfondir vos connaissances en utilisant async/await, la gestion des cookies et l'annulation de requêtes avec AbortController.