DEV Community

Cover image for Meilleures pratiques pour créer une application Express.js
Landry Bitege
Landry Bitege

Posted on

Meilleures pratiques pour créer une application Express.js

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;
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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 });
};
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode

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 });
Enter fullscreen mode Exit fullscreen mode
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);
  }
));
Enter fullscreen mode Exit fullscreen mode
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');
});
Enter fullscreen mode Exit fullscreen mode
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());
Enter fullscreen mode Exit fullscreen mode
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'));
Enter fullscreen mode Exit fullscreen mode

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 });
Enter fullscreen mode Exit fullscreen mode

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());
Enter fullscreen mode Exit fullscreen mode

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() });
});
Enter fullscreen mode Exit fullscreen mode
Mise à jour des dépendances

Utilisez npm audit et nsp pour vérifier et corriger les vulnérabilités.

Shell

npm audit
Enter fullscreen mode Exit fullscreen mode
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);
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode
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"]
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode

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);
    });
});
Enter fullscreen mode Exit fullscreen mode
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));
Enter fullscreen mode Exit fullscreen mode
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);
        }
    });
});
Enter fullscreen mode Exit fullscreen mode

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());
Enter fullscreen mode Exit fullscreen mode

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 :

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 !

Top comments (0)