Meilleures pratiques pour créer une application Express.js
Landry Bitege
Posted on June 13, 2024
Partie 2 : Meilleures pratiques et fonctionnalités avancées pour créer une application Express.js
Introduction
Pour la 1ère partie, je vous invite à visité l'article où j'ai parler de l'introduction d'express et ses concepts fondamentaux.
Si c'est déjà fait, ici on va voir des notion un peu avancer.
Dans le monde du développement web, il existe une multitude de bibliothèques et de frameworks disponibles pour résoudre une variété de problèmes. Bien que nous abordions certaines des options populaires dans cet article, l'objectif n'est pas de vous prescrire des solutions spécifiques, mais de vous montrer les bonnes pratiques et les concepts qui peuvent être appliqués avec différentes technologies selon vos préférences et vos besoins. Que vous choisissiez Mongoose ou un autre ODM, Passport.js ou une autre solution d'authentification, l'important est de comprendre comment intégrer et utiliser efficacement ces outils pour créer des applications Express.js robustes et évolutives. Explorons maintenant comment structurer et améliorer vos applications Express.js.
1. Structurer une application Express.js de manière organisée et évolutive
Architecture MVC (Model-View-Controller)
Modèles : Les modèles définissent les schémas de données et les interactions avec la base de données. Utilisez Mongoose pour MongoDB, par exemple.
JavaScript
// models/User.js
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
name: String,
email: String,
password: String,
});
const User = mongoose.model('User', userSchema);
module.exports = User;
Vues : Les vues gèrent les templates et le rendu des pages. Utilisez un moteur de templates comme EJS.
HTML
<!-- views/index.ejs -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Home</title>
</head>
<body>
<h1>Welcome, <%= user.name %></h1>
</body>
</html>
Contrôleurs : Les contrôleurs contiennent la logique des routes et des actions de l'application.
JavaScript
// controllers/userController.js
const User = require('../models/User');
exports.getUser = async (req, res) => {
const user = await User.findById(req.params.id);
res.render('index', { user });
};
Organisation des fichiers et dossiers
Organisez vos fichiers et dossiers de manière structurée pour maintenir la clarté et la facilité de maintenance.
myapp/
├── config/
│ └── config.js
├── controllers/
│ └── userController.js
├── middlewares/
│ └── auth.js
├── models/
│ └── User.js
├── routes/
│ └── userRoutes.js
├── views/
│ └── index.ejs
├── app.js
└── package.json
Utilisation d'un outil de scaffolding
Utilisez des générateurs comme Yeoman pour créer la structure de base de l'application.
Shell
npm install -g yo generator-express
yo express
2. Utiliser des modules et des bibliothèques tierces pour étendre les fonctionnalités d'Express
Mongoose pour MongoDB
Mongoose est un ODM (Object Data Modeling) pour MongoDB et Node.js.
JavaScript
// app.js
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/myapp', { useNewUrlParser: true, useUnifiedTopology: true });
Passport.js pour l'authentification
Passport.js permet d'implémenter facilement des stratégies d'authentification.
JavaScript
// config/passport.js
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const User = require('../models/User');
passport.use(new LocalStrategy(
async (username, password, done) => {
const user = await User.findOne({ username });
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.validPassword(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
}
));
Socket.io pour les communications en temps réel
Socket.io ajoute des fonctionnalités de WebSockets pour les applications en temps réel.
JavaScript
// app.js
const http = require('http');
const socketIo = require('socket.io');
const server = http.createServer(app);
const io = socketIo(server);
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
server.listen(3000, () => {
console.log('listening on *:3000');
});
Helmet pour la sécurité
Helmet aide à sécuriser l'application en configurant divers en-têtes HTTP.
JavaScript
// app.js
const helmet = require('helmet');
app.use(helmet());
Morgan pour la journalisation
Morgan est un middleware de journalisation des requêtes HTTP.
JavaScript
// app.js
const morgan = require('morgan');
app.use(morgan('combined'));
3. Gérer la sécurité des applications Express.js
Protection contre les attaques courantes
Injection SQL : Utilisez des ORM/ODM sécurisés et des requêtes paramétrées.
JavaScript
// Using Mongoose to avoid SQL injection
const user = await User.findOne({ username: req.body.username });
Cross-Site Scripting (XSS) : Échappez les données de l'utilisateur et utilisez des bibliothèques comme [xss-clean](https://www.npmjs.com/package/xss-clean)
.
JavaScript
const xss = require('xss-clean');
app.use(xss());
Cross-Site Request Forgery (CSRF) : Utilisez des tokens CSRF pour protéger les formulaires.
JavaScript
const csrf = require('csurf');
const csrfProtection = csrf({ cookie: true });
app.use(csrfProtection);
// In your route
app.get('/form', (req, res) => {
res.render('send', { csrfToken: req.csrfToken() });
});
Mise à jour des dépendances
Utilisez npm audit
et nsp
pour vérifier et corriger les vulnérabilités.
Shell
npm audit
Configurer HTTPS
Utilisez Let's Encrypt pour obtenir des certificats SSL/TLS gratuits.
JavaScript
const fs = require('fs');
const https = require('https');
const options = {
key: fs.readFileSync('/path/to/key.pem'),
cert: fs.readFileSync('/path/to/cert.pem')
};
https.createServer(options, app).listen(443);
4. Déployer et mettre à l'échelle une application Express.js
Héberger sur des plateformes cloud
Des plateformes comme Render, AWS, Heroku, et DigitalOcean facilitent le déploiement.
Shell
# Exemple de déploiement sur Heroku
heroku create
git push heroku master
Utilisation de Docker
Conteneurisez l'application pour un déploiement portable et reproductible.
# Dockerfile
FROM node:14
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]
Load balancing et scaling
Configurez un load balancer pour répartir le trafic et utilisez des outils comme PM2 pour gérer les processus Node.js.
Shell
# PM2
npm install pm2 -g
pm2 start app.js -i max
5. Bonnes pratiques pour le développement avec Express.js
Tests unitaires et d'intégration
Utilisez Mocha, Chai et Supertest pour écrire et exécuter des tests.
JavaScript
// test/user.test.js
const request = require('supertest');
const app = require('../app');
describe('GET /user', () => {
it('responds with json', (done) => {
request(app)
.get('/user')
.set('Accept', 'application/json')
.expect('Content-Type', /json/)
.expect(200, done);
});
});
Documentation
Utilisez des outils comme Swagger pour documenter les API.
JavaScript
const swaggerUi = require('swagger-ui-express');
const swaggerDocument = require('./swagger.json');
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
Optimisation des performances
Mise en cache avec Redis ou Memcached :
JavaScript
const redis = require('redis');
const client = redis.createClient();
app.get('/data', (req, res) => {
client.get('data', (err, data) => {
if (data) {
res.send(data);
} else {
// Fetch data from database
const newData = fetchDataFromDatabase();
client.setex('data', 3600, newData);
res.send(newData);
}
});
});
Optimiser les requêtes à la base de données :
Assurez-vous que vos requêtes sont optimisées et utilisez des index là où c'est nécessaire.
Utiliser des middlewares de compression comme [compression](https://www.npmjs.com/package/express-compression)
:
JavaScript
const compression = require('compression');
app.use(compression());
Conclusion
En suivant ces bonnes pratiques et en utilisant des fonctionnalités avancées, vous pouvez créer des applications Express.js robustes, sécurisées et évolutives. La structuration de votre code, l'utilisation de modules tiers, la gestion de la sécurité, le déploiement efficace et les tests rigoureux sont essentiels pour développer des applications performantes et maintenables. Continuez à explorer et à intégrer ces pratiques dans vos projets pour améliorer constamment la qualité de vos applications.
Voici quelques ressources supplémentaires qui pourraient vous aidez à continuer votre apprentissage :
- La documentation officielle d'Express.js sur les bonne pratiques de la securité en production
- Tutoriels et articles sur Express.js :
-
Livres sur Express.js :
- "Learning Express" de Carlos Rios
- "Building Node.js Applications" de Ryan Tozier et Ashish Goel
- Rejoignez la communauté Express.js : Participez à des forums et des groupes en ligne pour poser des questions, partager vos expériences et apprendre des autres développeurs.
- Construisez vos propres applications : La meilleure façon d'apprendre est de mettre la main à la pâte. Commencez par créer des applications simples et progressez vers des projets plus complexes.
N'oubliez jamais que l'apprentissage est un processus continu. Restez curieux, explorez et créez, et vous deviendrez un maître du développement d'applications Express.js !
Posted on June 13, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.