Table of Contents
Intégration de JavaScript avec les cadres de backend comme Node.js et Express
La possibilité d'utiliser JavaScript sur les côtés client et serveur a fondamentalement remodelé le développement web moderne. Node.js fournit l'environnement d'exécution qui rend cela possible, tandis qu'Express fournit un cadre mince et non opinionné qui rationalise la construction d'APIs robustes et de serveurs web. Ensemble, ils permettent aux développeurs de créer des applications évolutives en temps réel en utilisant une seule langue dans toute la pile.
Cet article couvre le paysage d'intégration complet : de la mise en place d'une fondation à la gestion des données, des intergiciels, de la sécurité, des tests et du déploiement. D'ici là, vous comprendrez comment concevoir des backends prêts à la production avec Node.js et Express, et comment les connecter parfaitement avec Frontend JavaScript.
Comprendre Node.js et Express
Node.js est un système d'exécution multiplateforme open source construit sur le moteur JavaScript Chrome. Il vous permet d'exécuter JavaScript en dehors d'un navigateur, sur le serveur. Son modèle d'E/S axé sur les événements et non-bloquant le rend particulièrement efficace pour les charges de travail d'E/S telles que les serveurs API, les applications en temps réel et les services de streaming.
Express est le cadre web le plus populaire pour Node.js. Il fournit un minimum de fonctionnalités pour la construction de serveurs Web et d'API, y compris le routage, le middleware et le modèle de support moteur. Express est non-opiné, ce qui signifie que vous êtes libre de structurer votre application comme vous le voyez en forme – un avantage qui donne aux équipes expérimentées flexibilité et contrôle.
Selon la documentation officielle Express , le cadre est -rapide, sans opinion, minimaliste. - Cette philosophie maintient la courbe d'apprentissage gérable tout en permettant des applications complexes et complètes.
Pourquoi utiliser Node.js et Express ensemble?
- Langue unifiée:[ JavaScript sur frontend et backend réduit la commutation de contexte et permet le partage de code (p. ex., logique de validation, utilitaires).
- Non-blocage I/O: Node.js gère efficacement de nombreuses connexions simultanées sans filetage lourd.
- L'écosystème de Rich: npm fournit des centaines de milliers de paquets, des pilotes de base de données aux bibliothèques d'authentification.
- Capacités en temps réel: Le support intégré de WebSockets via des bibliothèques comme s'intègre naturellement à Express.
Configuration d'un serveur de production-réapprovisionnement
Commencez par installer Node.js depuis nodejs.org. Après l'installation, créez un répertoire de projet et initialisez un paquet.json:
mkdir my-backend
cd my-backend
npm init -y
Installer Express comme une dépendance :
npm install express
Pour le développement, installez également pour redémarrer automatiquement le serveur sur les modifications de fichiers :
npm install -D nodemon
Maintenant créez un fichier avec un serveur minimal:
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.send('Hello, world!');
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Remarquez l'utilisation de , ce qui rend l'application portable dans différents environnements – une pratique exemplaire pour le déploiement.
Ajout de variables d'environnement
Utilisez le paquet pour charger des variables d'environnement à partir d'un fichier :
npm install dotenv
Créer un fichier :
PORT=5000
DB_CONNECTION_STRING=mongodb://localhost:27017/myapp
Dans , charger la configuration en haut:
require('dotenv').config();
Ce modèle maintient les données sensibles hors de votre base de codes et simplifie la gestion de la configuration.
Middleware: Le cœur de l'expression
Les fonctions Middleware sont les éléments constitutifs de la logique d'application Express. Elles ont accès à l'objet request, à l'objet response, et à la fonction . Elles peuvent exécuter du code, modifier la requête/réponse, mettre fin au cycle ou appeler le prochain middleware.
Les cas d'utilisation courante comprennent l'enregistrement, l'authentification, l'analyse des corps de requête et le traitement des erreurs.
Middleware intégré
Express fournit plusieurs fonctions de middleware intégrées:
- – Charges utiles JSON entrantes parses.
- – Parses corps encodés par URL (à partir de formulaires HTML).
- – Serve des fichiers statiques comme les images, CSS et JavaScript côté client.
Exemple avec l'analyse JSON :
app.use(express.json());
app.post('/api/users', (req, res) => {
console.log(req.body); // Access parsed JSON
res.json({ success: true });
});
Logiciels de milieu de vie personnalisés
Créez une logique réutilisable en écrivant votre propre middleware. Par exemple, un logger de requête :
const logger = (req, res, next) => {
console.log(`${req.method} ${req.url} - ${new Date().toISOString()}`);
next();
};
app.use(logger);
Ordre importe: intergiciel est exécuté dans l'ordre il est défini. Placez toujours le middleware de gestion des erreurs en dernier, avec quatre paramètres:
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Something broke!' });
});
APIs d'acheminement et de RESTful
Une structure de routage propre améliore la maintenance et l'évolutivité.
Routage de base
app.get('/api/items', (req, res) => {
// return list of items
});
app.post('/api/items', (req, res) => {
// create new item
});
app.put('/api/items/:id', (req, res) => {
const { id } = req.params;
// update item with given id
});
app.delete('/api/items/:id', (req, res) => {
// delete item
});
Utilisation du routeur Express pour la modularité
Pour les applications plus importantes, divisez les itinéraires en fichiers distincts en utilisant . Créez un dossier et un fichier :
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.json([{ id: 1, name: 'Sample Item' }]);
});
router.post('/', (req, res) => {
// create logic
});
module.exports = router;
Puis dans :
const itemsRouter = require('./routes/items');
app.use('/api/items', itemsRouter);
Cette approche maintient votre point d'entrée propre et les itinéraires logiquement groupés.
Connexion à une base de données
La plupart des moteurs de recherche doivent persister. Les bases de données populaires NoSQL et SQL s'intègrent bien à Node.js.
MongoDB avec Mongoose
Installez Mongoose, un ODM pour MongoDB :
npm install mongoose
Connectez-vous dans votre fichier serveur :
const mongoose = require('mongoose');
mongoose.connect(process.env.DB_CONNECTION_STRING)
.then(() => console.log('Connected to MongoDB'))
.catch(err => console.error('Connection error', err));
Définir un schéma et un modèle (par exemple ):
const mongoose = require('mongoose');
const itemSchema = new mongoose.Schema({
name: { type: String, required: true },
price: Number,
created_at: { type: Date, default: Date.now }
});
module.exports = mongoose.model('Item', itemSchema);
Utilisez le modèle dans vos itinéraires:
const Item = require('./models/Item');
app.post('/api/items', async (req, res) => {
try {
const item = new Item(req.body);
await item.save();
res.status(201).json(item);
} catch (err) {
res.status(400).json({ error: err.message });
}
});
PostgreSQLTM avec nœuds
Pour les bases de données relationnelles, utilisez le paquet :
npm install pg
Créer un pool et une requête :
const { Pool } = require('pg');
const pool = new Pool({
connectionString: process.env.DATABASE_URL
});
app.get('/api/users', async (req, res) => {
const result = await pool.query('SELECT * FROM users');
res.json(result.rows);
});
Envisager d'utiliser un ORM comme Séquelize[ ou [Knex[ pour des interactions plus abstraites.
Intégration Frontend-Backend
Une fois que le moteur de recherche sert des données via les paramètres d'API, votre frontend JavaScript peut les consommer en utilisant l'API ou des bibliothèques comme Axios.
Récupération depuis Express
Supposons que votre API Express fonctionne avec . Un script côté client (p. ex. Réaction, Vue ou HTML simple) peut récupérer des données :
fetch('http://localhost:3000/api/items')
.then(response => {
if (!response.ok) throw new Error('Network response error');
return response.json();
})
.then(data => {
console.log('Items:', data);
// render data on page
})
.catch(err => console.error('Fetch error:', err));
Manipulation du CORS
Lorsque le frontend et le backend sont sur différents ports ou domaines, vous devez activer le partage des ressources cross-origine (CORS). Installez le paquet :
npm install cors
Ensuite, utilisez-le comme intergiciel:
const cors = require('cors');
app.use(cors()); // Allows all origins – restrict in production
Pour la production, configurer les origines spécifiques:
app.use(cors({
origin: 'https://your-frontend-domain.com',
methods: ['GET', 'POST']
}));
Pratiques exemplaires en matière de sécurité
L'intégration des moteurs de recherche pose des problèmes de sécurité.
- Helmet: Définit différents en-têtes HTTP pour protéger contre les attaques courantes.
- Limite des taux : Utilisez pour prévenir les abus.
- Validation des entrées:[ Sanitiser et valider les entrées utilisateur en utilisant des bibliothèques comme ou .
- HTTPS: Toujours servir sur HTTPS en production.
- Authentification: Utiliser les jetons Web JSON (JWT) ou l'authentification basée sur la session avec .
Exemple avec casque:
const helmet = require('helmet');
app.use(helmet());
Exemple avec limite de taux:
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100
});
app.use('/api', limiter);
Gestion des erreurs et enregistrement
Les applications de production ont besoin d'une gestion robuste des erreurs. Créez un intergiciel centralisé de gestion des erreurs qui enregistre les erreurs et retourne des réponses cohérentes.
// Custom error handler
const errorHandler = (err, req, res, next) => {
console.error('Error:', err.message);
const statusCode = err.statusCode || 500;
res.status(statusCode).json({
error: err.message,
stack: process.env.NODE_ENV === 'development' ? err.stack : undefined
});
};
app.use(errorHandler);
Pour l'exploitation forestière, utilisez dans le développement et un bûcheron plus structuré comme dans la production:
npm install morgan winston
const morgan = require('morgan');
app.use(morgan('dev'));
Test de l'intégration
Les cadres de test populaires incluent Jest et Mocha. Pour les tests d'intégration HTTP, utilisez supertest.
Exemple avec Jest et Supertest
Installer les dépendances de la dev :
npm install -D jest supertest
Créer un fichier de test :
const request = require('supertest');
const app = require('./index'); // export app from index.js
describe('GET /api/items', () => {
it('responds with JSON array', async () => {
const res = await request(app)
.get('/api/items')
.expect('Content-Type', /json/)
.expect(200);
expect(Array.isArray(res.body)).toBe(true);
});
});
Note : Séparez la définition de l'application du serveur qui écoute pour éviter les conflits de port pendant les tests. Exportez l'application et écoutez seulement lorsque le fichier est lancé directement :
if (require.main === module) {
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
}
module.exports = app;
Considérations relatives au déploiement
Lors du déploiement de votre moteur Node.js+Express, suivez les directives suivantes :
- Utilisez un gestionnaire de processus comme PM2 pour garder l'application en vie et gérer le regroupement.
- Set environnementaux variables[ sur la plateforme d'hébergement (par exemple Heroku, DigitalOcean, AWS Elastic Beanstalk).
- Activer la logarithme et la surveillance avec des services comme Logtail ou Datadog.
- Utilisez un proxy inversé (Nginx, Caddy) pour les en-têtes de terminaison SSL, de cache et de sécurité.
Un modèle de déploiement commun est de garder le moteur et le frontend comme des projets séparés, en communiquant via API sur HTTPS. Vous pouvez également servir les fichiers de construction frontend via Express en utilisant et gérer toutes les routes de capture pour supporter le routage côté client (par exemple, React Router).
Optimisation des performances
Node.js est à jeun, mais vous pouvez encore atteindre un débit élevé avec des stratégies appropriées:
- Utilisez async/attendu pour toutes les opérations d'E/S afin d'éviter de bloquer la boucle d'événement.
- Réponses de compression avec intergiciel.
- Cache réponses fréquentes en utilisant des magasins en mémoire comme Redis.
- Cluster l'application sur plusieurs cœurs de processeurs en utilisant le module intégré ou le mode de cluster PM2.
Exemple avec compression:
const compression = require('compression');
app.use(compression());
Communication en temps réel avec les serveurs Web
Express s'intègre en douceur avec pour permettre une communication bidirectionnelle, basée sur des événements. C'est idéal pour les applications de chat, les notifications en direct et les outils collaboratifs.
npm install socket.io
Créez le serveur avec le support HTTP et WebSocket :
const http = require('http');
const socketIo = require('socket.io');
const server = http.createServer(app);
const io = socketIo(server, { cors: { origin: '*' } });
io.on('connection', (socket) => {
console.log('New client connected');
socket.on('disconnect', () => console.log('Client disconnected'));
});
server.listen(PORT, () => console.log(`Server with WebSocket on port ${PORT}`));
Le frontend peut se connecter à ce serveur WebSocket et émettre/écouter des événements en utilisant la bibliothèque .
Cadres et modèles à empiler
Au-delà de l'intégration de base, de nombreuses équipes adoptent des cadres qui combinent Node.js, Express et un cadre frontal en une pile cohésive. Le plus commun est la pile MERN (MongoDB, Express, React, Node.js).
Ces piles permettent aux développeurs de construire des applications complètes de la base de données à l'interface utilisateur, souvent avec des modèles et types partagés. Par exemple, vous pouvez définir les schémas de Mongoose sur le moteur et réutiliser la même logique de validation sur la façade après conversion en bibliothèque de formulaires.
Conclusion
L'intégration de JavaScript avec Node.js et Express ne se limite pas à l'utilisation de codes similaires des deux côtés, mais à la mise à profit de la pleine puissance de l'écosystème JavaScript pour construire des applications web cohésives, durables et performantes. De la configuration de base aux modèles avancés comme les middleware, l'intégration de bases de données, l'authentification et les fonctionnalités en temps réel, Express offre la flexibilité nécessaire pour s'adapter aux diverses exigences du projet.
En maîtrisant ces techniques, vous pouvez éliminer l'inadéquation d'impédance entre backend et frontend, accélérer les cycles de développement et déployer des applications à cette échelle. Il est temps de mettre la théorie en pratique : lancer un nouveau projet, expérimenter avec le middleware, connecter une base de données, et voir l'intégration prendre vie.