Back-end angularforall.com

- API REST avec Node.js et Express : guide complet

Node-Js Express Api Rest Rest-Api Javascript Backend Middleware Routing Validation Error-Handling Structure-Projet Mvc Npm
API REST avec Node.js et Express : guide complet

Construisez une API REST avec Node.js et Express : configuration des routes, middlewares d'authentification, gestion des erreurs et structure de projet propre.

Objectif de l'article

Construisez une API REST avec Node.js et Express : configuration des routes, middlewares d'authentification, gestion des erreurs et structure de projet propre.

A retenir: avance par itération, mesure les impacts, puis industrialise.

Concepts clés

Avant de démarrer votre projet Express, voici les concepts fondamentaux à maîtriser :

  • Node.js : runtime JavaScript côté serveur, asynchrone et event-driven
  • Express : framework léger et flexible pour créer des serveurs HTTP et des APIs REST
  • Routes : chemins HTTP (GET, POST, PUT, DELETE) qui mappent à des contrôleurs
  • Middlewares : fonctions qui traitent les requêtes avant d'atteindre les routes
  • RESTful : convention de conception utilisant les verbes HTTP pour manipuler des ressources
  • JSON : format de données standard pour les APIs modernes
  • npm : gestionnaire de paquets pour gérer les dépendances Node.js

Implémentation

Étape 1 : Initialiser le projet

Créez un dossier pour votre projet et initialisez npm :

mkdir mon-api-express
cd mon-api-express
npm init -y
npm install express cors dotenv

Étape 2 : Créer le serveur principal

Créez un fichier server.js à la racine :

const express = require('express');
const cors = require('cors');
require('dotenv').config();

const app = express();
const PORT = process.env.PORT || 3000;

// Middlewares globaux
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// Routes
app.get('/api/health', (req, res) => {
  res.json({ status: 'OK', timestamp: new Date() });
});

// Gestion des erreurs 404
app.use((req, res) => {
  res.status(404).json({ error: 'Route non trouvée' });
});

// Démarrer le serveur
app.listen(PORT, () => {
  console.info(`Serveur lancé sur http://localhost:${PORT}`);
});

Étape 3 : Créer une structure modulaire avec des routes

Créez un dossier routes et ajoutez un fichier products.js :

const express = require('express');
const router = express.Router();

// Données exemple
let products = [
  { id: 1, name: 'Produit 1', price: 29.99 },
  { id: 2, name: 'Produit 2', price: 49.99 }
];

// GET tous les produits
router.get('/', (req, res) => {
  res.json(products);
});

// GET un produit par ID
router.get('/:id', (req, res) => {
  const product = products.find(p => p.id === parseInt(req.params.id));
  if (!product) {
    return res.status(404).json({ error: 'Produit non trouvé' });
  }
  res.json(product);
});

// POST créer un produit
router.post('/', (req, res) => {
  const { name, price } = req.body;

  if (!name || !price) {
    return res.status(400).json({ error: 'name et price sont requis' });
  }

  const newProduct = {
    id: Math.max(...products.map(p => p.id), 0) + 1,
    name,
    price
  };

  products.push(newProduct);
  res.status(201).json(newProduct);
});

// PUT mettre à jour un produit
router.put('/:id', (req, res) => {
  const product = products.find(p => p.id === parseInt(req.params.id));
  if (!product) {
    return res.status(404).json({ error: 'Produit non trouvé' });
  }

  if (req.body.name) product.name = req.body.name;
  if (req.body.price) product.price = req.body.price;

  res.json(product);
});

// DELETE supprimer un produit
router.delete('/:id', (req, res) => {
  const index = products.findIndex(p => p.id === parseInt(req.params.id));
  if (index === -1) {
    return res.status(404).json({ error: 'Produit non trouvé' });
  }

  const deleted = products.splice(index, 1);
  res.json(deleted[0]);
});

module.exports = router;

Étape 4 : Intégrer les routes dans server.js

const productRoutes = require('./routes/products');

// Intégrer les routes
app.use('/api/products', productRoutes);

Étape 5 : Créer un middleware personnalisé

Créez un fichier middlewares/logger.js :

const logger = (req, res, next) => {
  console.info(`${new Date().toISOString()} - ${req.method} ${req.path}`);
  next();
};

module.exports = logger;

Utilisez-le dans votre serveur :

const logger = require('./middlewares/logger');
app.use(logger);

Étape 6 : Ajouter des variables d'environnement

Créez un fichier .env :

PORT=3000
NODE_ENV=development
DB_URL=mongodb://localhost:27017/mon-api

Et un fichier .env.example pour la documentation :

PORT=3000
NODE_ENV=development
DB_URL=mongodb://localhost:27017/mon-api

Intégration en production

Bonnes pratiques de sécurité

  • Valider les entrées : Toujours valider et nettoyer les données reçues
  • Gérer les erreurs : Ne pas exposer les détails internes des erreurs
  • HTTPS obligatoire : Utiliser HTTPS en production (certificat SSL/TLS)
  • Rate limiting : Limiter le nombre de requêtes par client avec un middleware
  • CORS configuré : Définir les origines autorisées, pas * en production
  • Authentication : Implémenter JWT ou sessions sécurisées
  • Logging sécurisé : Logger les erreurs sans exposer les secrets

Exemple de gestion d'erreurs centralisée

// Middleware de gestion d'erreurs (à la fin de server.js)
app.use((err, req, res, next) => {
  console.error(err.stack);

  const status = err.status || 500;
  const message = process.env.NODE_ENV === 'production'
    ? 'Erreur serveur'
    : err.message;

  res.status(status).json({ error: message });
});

Lancer l'application en production

  • Utiliser un process manager comme PM2
  • Configurer les variables d'environnement pour la prod
  • Mettre en place un reverse proxy (Nginx) devant Express
  • Configurer les logs et la surveillance (monitoring)
  • Utiliser Docker pour standardiser l'environnement
  • Automatiser le déploiement avec CI/CD

Installer et lancer avec PM2

npm install -g pm2
pm2 start server.js --name "mon-api"
pm2 save
pm2 startup

Configuration Nginx exemple

server {
    listen 80;
    server_name api.example.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}

Tester votre API

Utilisez curl ou Postman pour tester :

# GET tous les produits
curl http://localhost:3000/api/products

# POST créer un produit
curl -X POST http://localhost:3000/api/products \
  -H "Content-Type: application/json" \
  -d '{"name":"Nouveau produit","price":99.99}'

# GET un produit
curl http://localhost:3000/api/products/1

# PUT mettre à jour
curl -X PUT http://localhost:3000/api/products/1 \
  -H "Content-Type: application/json" \
  -d '{"name":"Produit modifié"}'

# DELETE
curl -X DELETE http://localhost:3000/api/products/1

Prochaines étapes

  • Ajouter une base de données (MongoDB, PostgreSQL)
  • Implémenter l'authentification JWT
  • Créer des tests unitaires avec Jest
  • Ajouter la validation avec Joi ou Zod
  • Mettre en place une documentation Swagger/OpenAPI

Partager