Objectifs pédagogiques :
- Comprendre et implémenter des middlewares Express
- Créer des routes RESTful pour une ressource
- Gérer les différentes méthodes HTTP (GET, POST, PATCH, DELETE)
- Structurer une API REST simple
Partie 1 : Initialisation du projet
1.1 Création du projet
# Créer le dossier du projet
mkdir tp-express-api
cd tp-express-api
npm init -y
npm install express
npm install -D nodemon
1.2 Structure du projet
tp-express-api/
├── package.json
├── server.js
└── data/
└── posts.json
├── package.json
├── server.js
└── data/
└── posts.json
1.3 Configuration package.json
Modifiez le fichier package.json pour ajouter les scripts :
{
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js"
}
}
1.4 Données initiales
Créez le fichier data/posts.json :
[
{
"id": 1,
"title": "Introduction à Express.js",
"content": "Express est un framework web minimaliste pour Node.js",
"author": "Ahmed",
"createdAt": "2024-01-15T10:00:00Z"
},
{
"id": 2,
"title": "Les API REST",
"content": "REST est un style architectural pour les services web",
"author": "Fatima",
"createdAt": "2024-01-16T14:30:00Z"
}
]
Partie 2 : Mise en place du serveur Express
2.1 Serveur de base
Créez le fichier server.js :
const express = require('express');
const fs = require('fs').promises;
const path = require('path');
const app = express();
const PORT = 3000;
// TODO: Ajouter le middleware pour parser le JSON
// TODO: Démarrer le serveur sur le port 3000
2.2 Middleware de logging
Ajoutez un middleware personnalisé pour logger les requêtes :
// TODO: Créer un middleware qui log la date, la méthode HTTP et l'URL
// Format attendu: [2024-01-15T10:00:00.000Z] GET /api/posts
2.3 Fonctions utilitaires
Ajoutez ces fonctions pour gérer les données :
// Chemin vers le fichier de données
const POSTS_FILE = path.join(__dirname, 'data', 'posts.json');
// TODO: Implémenter la fonction readPosts()
// Cette fonction doit lire le fichier posts.json et retourner un tableau d'objets
async function readPosts() {
// TODO
}
// TODO: Implémenter la fonction writePosts(posts)
// Cette fonction doit écrire le tableau posts dans le fichier posts.json
async function writePosts(posts) {
// TODO
}
// TODO: Implémenter la fonction getNextId()
// Cette fonction doit retourner le prochain ID disponible
async function getNextId() {
// TODO
}
Partie 3 : Implémentation des routes CRUD
3.1 GET /api/posts - Récupérer tous les posts
// TODO: Créer la route GET /api/posts
// Cette route doit retourner tous les posts au format :
// {
// success: true,
// count: nombre_de_posts,
// data: [array_des_posts]
// }
3.2 GET /api/posts/:id - Récupérer un post par ID
// TODO: Créer la route GET /api/posts/:id
// Cette route doit :
// - Récupérer l'ID depuis req.params.id
// - Chercher le post correspondant
// - Retourner 404 si non trouvé
// - Retourner le post si trouvé
3.3 POST /api/posts - Créer un nouveau post
D'abord, créez un middleware de validation :
// TODO: Créer le middleware validatePost
// Ce middleware doit vérifier que title, content et author sont présents
// Si non, retourner une erreur 400
const validatePost = (req, res, next) => {
// TODO
};
Puis, créez la route POST :
// TODO: Créer la route POST /api/posts avec le middleware validatePost
// Cette route doit :
// - Créer un nouveau post avec un ID généré
// - Ajouter createdAt avec la date actuelle
// - Sauvegarder dans le fichier
// - Retourner le post créé avec status 201
3.4 PATCH /api/posts/:id - Mettre à jour un post
// TODO: Créer la route PATCH /api/posts/:id
// Cette route doit :
// - Permettre la mise à jour partielle
// - Ne pas permettre la modification de l'ID
// - Ajouter un champ updatedAt
// - Retourner 404 si le post n'existe pas
3.5 DELETE /api/posts/:id - Supprimer un post
// TODO: Créer la route DELETE /api/posts/:id
// Cette route doit :
// - Supprimer le post correspondant à l'ID
// - Retourner 404 si le post n'existe pas
// - Retourner un message de succès si supprimé
3.6 Middleware de gestion des routes non trouvées
// TODO: Ajouter un middleware pour gérer les routes non trouvées
// Ce middleware doit retourner une erreur 404
// IMPORTANT: Ce middleware doit être placé en dernier
Partie 4 : Tests et validation
4.1 Fichier de test HTTP
Créez un fichier test.http pour tester votre API avec l'extension REST Client :
### Variables
@baseUrl = http://localhost:3000/api/posts
### Récupérer tous les posts
GET {{baseUrl}}
### Récupérer un post spécifique
GET {{baseUrl}}/1
### Créer un nouveau post
POST {{baseUrl}}
Content-Type: application/json
{
"title": "Mon nouveau post",
"content": "Contenu intéressant sur Express.js",
"author": "Youssef"
}
### Mettre à jour un post
PATCH {{baseUrl}}/1
Content-Type: application/json
{
"title": "Titre modifié"
}
### Supprimer un post
DELETE {{baseUrl}}/2
### Tester une route inexistante
GET http://localhost:3000/route-inexistante
### Tester POST sans données (devrait retourner 400)
POST {{baseUrl}}
Content-Type: application/json
{}
### Tester GET avec ID inexistant (devrait retourner 404)
GET {{baseUrl}}/999
Exercices supplémentaires
Exercice 1 : Pagination
Ajoutez la pagination à la route GET /api/posts avec les paramètres limit et page.
Exemple : /api/posts?limit=10&page=2
Exercice 2 : Filtrage
Permettez le filtrage par auteur.
Exemple : /api/posts?author=Ahmed
Exercice 3 : Tri
Ajoutez le tri par date de création.
Exemple : /api/posts?sort=createdAt&order=desc
Exercice 4 : Middleware d'authentification
Créez un middleware simple qui vérifie la présence d'un header X-API-Key.