Logo Express.js

Express.js

Un framework web minimaliste et flexible pour Icône Node.jsNode.js qui permet de créer rapidement des API robustes et des applications web performantes.

Pour les non-initiés

Qu'est-ce que Express.js ?

Imaginez que vous construisiez une maison. Vous pourriez fabriquer chaque outil et chaque matériau vous-même, ou bien utiliser des outils spécialisés et des matériaux prêts à l'emploi pour accélérer considérablement la construction.

Express.js est comme une boîte à outils complète pour les développeurs qui souhaitent construire des sites web et des applications avec Icône Node.jsNode.js. C'est un framework qui fournit des solutions prêtes à l'emploi pour les défis courants du développement web, sans imposer de structure rigide.

Pourquoi Express.js est si populaire ?

Simplicité et rapidité

Express.js permet de démarrer rapidement un projet, avec une courbe d'apprentissage douce et une absence de configuration complexe.

Flexibilité

Contrairement à d'autres frameworks qui imposent une structure rigide, Express.js laisse les développeurs organiser leur code comme ils le souhaitent.

En résumé, Express.js est la solution idéale pour créer des sites web, des applications et des API modernes, en simplifiant considérablement le processus de développement tout en offrant la flexibilité nécessaire pour s'adapter à différents besoins.

Pour les développeurs

Fonctionnement technique

Express.js est un framework web minimaliste pour Icône Node.jsNode.js qui facilite la création d'applications et d'API web. Il repose sur le module HTTP de Node.js et ajoute une couche d'abstraction pour simplifier les tâches courantes du développement web.

Mise en place d'un serveur de base

Serveur Express.js minimal

Voici comment démarrer rapidement un serveur Express.js :

app.js
const express = require('express'); const app = express(); const port = process.env.PORT || 3000; // Middleware pour parser le JSON app.use(express.json()); app.use(express.urlencoded({ extended: true })); // Route simple app.get('/', (req, res) => { res.send('Bienvenue sur notre API Express.js !'); }); // Démarrage du serveur app.listen(port, () => { console.log(`Serveur démarré sur http://localhost:${port}`); });

Routage

Le routage est l'un des aspects fondamentaux d'Express.js. Il permet de définir comment l'application répond aux requêtes client pour un endpoint et une méthode HTTP spécifiques.

routes/users.js
// routes/users.js const express = require('express'); const router = express.Router(); // Liste tous les utilisateurs router.get('/', (req, res) => { res.json({ users: [ { id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' } ]}); }); // Récupère un utilisateur par ID router.get('/:id', (req, res) => { const userId = parseInt(req.params.id); // Simulation d'accès à une base de données const user = { id: userId, name: `Utilisateur ${userId}` }; res.json(user); }); // Crée un nouvel utilisateur router.post('/', (req, res) => { // Validation des données if (!req.body.name) { return res.status(400).json({ error: 'Le nom est requis' }); } // Simulation de création en base de données const newUser = { id: 4, name: req.body.name, createdAt: new Date() }; res.status(201).json(newUser); }); // Exporte le router pour l'utiliser dans l'application principale module.exports = router; // Dans app.js const usersRouter = require('./routes/users'); app.use('/api/users', usersRouter);

Middleware

Les middlewares sont des fonctions qui ont accès à l'objet de requête (req), à l'objet de réponse (res) et à la fonction suivante dans le cycle requête-réponse. Ils peuvent exécuter du code, modifier les objets de requête et de réponse, terminer le cycle, ou appeler le prochain middleware.

middleware/auth.js
// Middleware d'authentification const authenticate = (req, res, next) => { const authHeader = req.headers.authorization; if (!authHeader || !authHeader.startsWith('Bearer ')) { return res.status(401).json({ error: 'Token d'authentification manquant' }); } const token = authHeader.split(' ')[1]; try { // Dans un cas réel, on vérifierait le token JWT // const user = jwt.verify(token, process.env.JWT_SECRET); // req.user = user; // Simulation pour l'exemple req.user = { id: 1, role: 'admin' }; next(); } catch (error) { res.status(401).json({ error: 'Token invalide' }); } }; // Middleware pour vérifier les droits administrateur const isAdmin = (req, res, next) => { if (req.user && req.user.role === 'admin') { next(); } else { res.status(403).json({ error: 'Accès refusé' }); } }; // Utilisation des middlewares sur une route sensible app.get('/api/admin/dashboard', authenticate, isAdmin, (req, res) => { res.json({ message: 'Bienvenue sur le dashboard administrateur', user: req.user }); });

Gestion des erreurs

Express.js permet une gestion centralisée des erreurs grâce à un middleware spécial qui prend quatre arguments (err, req, res, next).

error-handling.js
// Middleware de gestion globale des erreurs app.use((err, req, res, next) => { console.error(err.stack); // Erreurs opérationnelles vs erreurs de programmation if (err.isOperational) { return res.status(err.statusCode || 500).json({ status: 'error', message: err.message }); } // Erreurs inattendues - ne pas exposer les détails en production res.status(500).json({ status: 'error', message: process.env.NODE_ENV === 'production' ? 'Une erreur interne est survenue' : err.message }); }); // Class d'erreur personnalisée class AppError extends Error { constructor(message, statusCode) { super(message); this.statusCode = statusCode; this.isOperational = true; Error.captureStackTrace(this, this.constructor); } } // Exemple d'utilisation dans une route app.get('/api/products/:id', async (req, res, next) => { try { const product = await Product.findById(req.params.id); if (!product) { return next(new AppError('Produit non trouvé', 404)); } res.json(product); } catch (err) { next(err); } });

Architecture MVC

Bien qu'Express.js ne force pas l'utilisation d'un pattern spécifique, il est courant d'organiser les applications avec le pattern MVC (Modèle-Vue-Contrôleur).

MVC Pattern
// models/userModel.js const mongoose = require('mongoose'); const bcrypt = require('bcrypt'); const userSchema = new mongoose.Schema({ email: { type: String, required: [true, 'Un email est requis'], unique: true, lowercase: true }, password: { type: String, required: [true, 'Un mot de passe est requis'], minlength: 8, select: false }, name: { type: String, required: [true, 'Un nom est requis'] }, createdAt: { type: Date, default: Date.now } }); // Méthode pour comparer des mots de passe userSchema.methods.checkPassword = async function(candidatePassword, userPassword) { return await bcrypt.compare(candidatePassword, userPassword); }; // Hashage du mot de passe avant sauvegarde userSchema.pre('save', async function(next) { if (!this.isModified('password')) return next(); this.password = await bcrypt.hash(this.password, 12); next(); }); const User = mongoose.model('User', userSchema); module.exports = User; // controllers/authController.js const User = require('../models/userModel'); const jwt = require('jsonwebtoken'); const { promisify } = require('util'); exports.signup = async (req, res, next) => { try { const newUser = await User.create({ name: req.body.name, email: req.body.email, password: req.body.password }); const token = jwt.sign( { id: newUser._id }, process.env.JWT_SECRET, { expiresIn: process.env.JWT_EXPIRES_IN } ); res.status(201).json({ status: 'success', token, data: { user: { id: newUser._id, name: newUser.name, email: newUser.email } } }); } catch (err) { next(err); } }; // routes/authRoutes.js const express = require('express'); const authController = require('../controllers/authController'); const router = express.Router(); router.post('/signup', authController.signup); router.post('/login', authController.login); module.exports = router;

Intégration avec des API externes

Express.js facilite la création de services qui interagissent avec des API tierces :

API Integration
// services/weatherService.js const axios = require('axios'); exports.getWeatherByCity = async (city) => { try { const response = await axios.get(`https://api.openweathermap.org/data/2.5/weather`, { params: { q: city, appid: process.env.WEATHER_API_KEY, units: 'metric' } }); return { city: response.data.name, country: response.data.sys.country, temperature: response.data.main.temp, description: response.data.weather[0].description, icon: response.data.weather[0].icon, humidity: response.data.main.humidity, windSpeed: response.data.wind.speed }; } catch (error) { if (error.response && error.response.status === 404) { throw new Error('Ville non trouvée'); } throw new Error('Erreur lors de la récupération des données météo'); } }; // controllers/weatherController.js const weatherService = require('../services/weatherService'); exports.getWeather = async (req, res, next) => { try { const { city } = req.params; if (!city) { return res.status(400).json({ status: 'error', message: 'Veuillez fournir un nom de ville' }); } const weatherData = await weatherService.getWeatherByCity(city); res.json({ status: 'success', data: weatherData }); } catch (err) { next(err); } }; // routes/weatherRoutes.js const express = require('express'); const weatherController = require('../controllers/weatherController'); const router = express.Router(); router.get('/:city', weatherController.getWeather); module.exports = router;

Avantages techniques

  • Performance - Express.js est léger et fonctionne sur la plateforme asynchrone de Node.js
  • Écosystème riche - Accès à une vaste collection de middlewares pour diverses fonctionnalités
  • Routage puissant - Système de routage flexible qui prend en charge les paramètres et les modèles
  • Templates - Support pour de nombreux moteurs de templates comme Pug, EJS, Handlebars
  • Middleware modulaire - Système de middleware extensible pour personnaliser le comportement de l'application

Cas d'usage idéaux

  • APIs RESTful - Création rapide d'API scalables et maintenables
  • Applications en temps réel - Combiné avec Socket.io pour des fonctionnalités en temps réel
  • Applications single-page - Backend pour des SPA développés avec Icône ReactReact, Angular ou Vue.js
  • Microservices - Développement de services légers et indépendants
  • Prototypes rapides - Mise en place rapide de MVPs et de preuves de concept
Applications concrètes

Cas d'usage

APIs RESTful

Express.js excelle dans la création d'APIs Icône RESTREST performantes et bien structurées, avec un routage clair et un support JSON natif.

Applications en temps réel

Combiné avec Socket.io, Express.js est idéal pour créer des applications de chat, des tableaux de bord en direct, ou des jeux multijoueurs avec des mises à jour instantanées.

Backends pour SPAs

Parfait comme backend léger pour les applications single-page développées avec Icône ReactReact, Angular ou Icône Vue.jsVue.js.

Microservices

La légèreté et la flexibilité d'Express.js en font un choix excellent pour développer des microservices spécifiques dans une architecture distribuée.

Entreprises qui utilisent Express.js

De nombreuses entreprises de premier plan font confiance à Express.js pour leurs applications :

Netflix
Uber
IBM
Accenture
Fox Sports
PayPal
Myntra
GoDaddy