OUJOOD.COM
Introduction à Node.js et MySQL
Node.js est devenu l'un des environnements d'exécution JavaScript les plus populaires pour le développement backend, tandis que MySQL reste l'une des bases de données relationnelles les plus utilisées au monde. Dans ce tutoriel complet, vous apprendrez à connecter Node.js à une base de données MySQL, à exécuter des requêtes SQL en toute sécurité et à afficher les résultats dans une page HTML responsive.
Ce guide pratique est conçu pour les débutants comme pour les développeurs intermédiaires, avec des exemples de code détaillés, des explications claires et des bonnes pratiques de sécurité. À la fin de ce tutoriel, vous serez capable de créer des applications web complètes utilisant Node.js et MySQL.
Prérequis pour suivre ce tutoriel
Avant de commencer ce tutoriel Node.js avec MySQL, assurez-vous d'avoir les éléments suivants :
- 📌 Node.js (version 14 ou supérieure) installé sur votre machine. Téléchargez la dernière version LTS depuis nodejs.org.
🎥 Regardez notre guide vidéo pour installer Node.js - 📌 MySQL Server (version 5.7 ou supérieure) ou MariaDB. Téléchargez MySQL gratuitement à mysql.com/downloads.
🎥 Regardez notre guide pour l'installation de MySQL - 📌 Un éditeur de code moderne, comme Visual Studio Code, Sublime Text ou WebStorm.
📽️ Regardez notre guide pour installer Visual Studio Code - 📌 Des connaissances de base en JavaScript et en SQL
Étape 1 : Installation et configuration de MySQL
La première étape pour connecter Node.js à MySQL consiste à installer et configurer votre serveur de base de données. Si vous n'avez pas encore installé MySQL, téléchargez-le gratuitement depuis le site officiel :
Télécharger MySQL Community Server
Une fois MySQL installé et le serveur démarré, ouvrez votre client MySQL (MySQL Workbench, ligne de commande ou phpMyAdmin) et créez une base de données de test nommée test_db avec une table clients en exécutant les commandes SQL suivantes :
-- Création de la base de données
CREATE DATABASE IF NOT EXISTS test_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE test_db;
-- Création de la table clients
CREATE TABLE clients (
id INT AUTO_INCREMENT PRIMARY KEY,
nom VARCHAR(100) NOT NULL,
email VARCHAR(150) NOT NULL UNIQUE,
date_creation TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;
-- Insertion de données de test
INSERT INTO clients (nom, email) VALUES
('Jean Dupont', 'jean.dupont@example.com'),
('Marie Martin', 'marie.martin@example.com'),
('Pierre Durand', 'pierre.durand@example.com');
Note : Nous utilisons le charset utf8mb4 pour supporter tous les caractères Unicode, y compris les emojis. La contrainte UNIQUE sur l'email empêche les doublons.
Étape 2 : Configuration du projet Node.js
Créez un nouveau dossier pour votre projet Node.js et MySQL, puis initialisez un projet npm pour gérer les dépendances :
mkdir node-mysql-tutorial cd node-mysql-tutorial npm init -y
Cette commande crée un fichier package.json qui contiendra toutes les informations sur votre projet et ses dépendances.
Ensuite, installez les packages npm nécessaires pour connecter Node.js à MySQL :
npm install mysql2 express dotenv
Explication des packages :
mysql2: driver MySQL moderne pour Node.js avec support des Promises et de meilleures performancesexpress: framework web minimaliste pour créer le serveur HTTPdotenv: pour gérer les variables d'environnement et sécuriser les identifiants de connexion
Étape 3 : Sécurisation des identifiants avec .env
Pour des raisons de sécurité, ne stockez jamais vos identifiants de base de données directement dans le code. Créez un fichier .env à la racine de votre projet :
DB_HOST=localhost DB_USER=votre_utilisateur DB_PASSWORD=votre_mot_de_passe DB_NAME=test_db DB_PORT=3306 PORT=3000
Important : Ajoutez .env à votre fichier .gitignore pour éviter de publier vos identifiants sur GitHub ou autres dépôts publics.
Étape 4 : Créer le serveur Node.js avec Express et MySQL
Créez un fichier server.js qui gérera la connexion à MySQL et servira l'application web. Ce fichier utilise les bonnes pratiques de sécurité et de gestion des erreurs :
// Chargement des variables d'environnement
require('dotenv').config();
const express = require('express');
const mysql = require('mysql2');
const app = express();
const port = process.env.PORT || 3000;
// Configuration de la connexion MySQL avec pool de connexions
const pool = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
port: process.env.DB_PORT || 3306,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
// Conversion du pool en version Promise pour async/await
const promisePool = pool.promise();
// Middleware pour parser le JSON
app.use(express.json());
// Middleware pour servir les fichiers statiques
app.use(express.static('public'));
// Test de connexion à la base de données
pool.getConnection((err, connection) => {
if (err) {
console.error("❌ Erreur de connexion à MySQL :", err.message);
return;
}
console.log("✅ Connecté à la base de données MySQL !");
connection.release(); // Libérer la connexion
});
// Route pour servir la page HTML principale
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
// Route API pour récupérer tous les clients
app.get('/api/clients', async (req, res) => {
try {
const [rows] = await promisePool.query('SELECT * FROM clients ORDER BY id DESC');
res.json({
success: true,
data: rows,
count: rows.length
});
} catch (error) {
console.error("❌ Erreur lors de la requête :", error.message);
res.status(500).json({
success: false,
message: "Erreur lors de la récupération des données",
error: error.message
});
}
});
// Route API pour récupérer un client par ID
app.get('/api/clients/:id', async (req, res) => {
try {
const [rows] = await promisePool.query(
'SELECT * FROM clients WHERE id = ?',
[req.params.id]
);
if (rows.length === 0) {
return res.status(404).json({
success: false,
message: "Client non trouvé"
});
}
res.json({
success: true,
data: rows[0]
});
} catch (error) {
console.error("❌ Erreur :", error.message);
res.status(500).json({
success: false,
message: "Erreur serveur"
});
}
});
// Gestion des routes non trouvées
app.use((req, res) => {
res.status(404).json({
success: false,
message: "Route non trouvée"
});
});
// Démarrage du serveur
app.listen(port, () => {
console.log(`🚀 Serveur démarré sur http://localhost:${port}`);
});
Bonnes pratiques implémentées :
- Utilisation d'un pool de connexions pour de meilleures performances
- Gestion des erreurs avec
try/catchetasync/await - Paramètres de requête sécurisés avec
?pour éviter les injections SQL - Variables d'environnement pour la sécurité
- API RESTful avec réponses JSON structurées
Étape 5 : Créer la page HTML responsive
Créez un fichier index.html moderne et responsive pour afficher les données MySQL. Ce fichier utilise JavaScript moderne avec fetch API et gestion des erreurs :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Application de gestion de clients avec Node.js et MySQL">
<title>Gestion des Clients - Node.js MySQL</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: white;
border-radius: 12px;
box-shadow: 0 10px 40px rgba(0,0,0,0.1);
overflow: hidden;
}
header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 30px;
text-align: center;
}
header h1 {
font-size: 2em;
margin-bottom: 10px;
}
.stats {
display: flex;
justify-content: center;
gap: 20px;
margin-top: 15px;
flex-wrap: wrap;
}
.stat-card {
background: rgba(255,255,255,0.2);
padding: 10px 20px;
border-radius: 8px;
}
main {
padding: 30px;
}
.loading {
text-align: center;
padding: 40px;
color: #667eea;
font-size: 1.2em;
}
.error {
background: #fee;
border-left: 4px solid #f44;
padding: 15px;
margin: 20px 0;
border-radius: 4px;
color: #c33;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
thead {
background: #f8f9fa;
}
th {
padding: 15px;
text-align: left;
font-weight: 600;
color: #333;
border-bottom: 2px solid #dee2e6;
}
td {
padding: 15px;
border-bottom: 1px solid #dee2e6;
}
tbody tr {
transition: background 0.2s;
}
tbody tr:hover {
background: #f8f9fa;
}
.badge {
display: inline-block;
padding: 4px 12px;
border-radius: 12px;
font-size: 0.85em;
font-weight: 600;
background: #667eea;
color: white;
}
@media (max-width: 768px) {
table {
font-size: 0.9em;
}
th, td {
padding: 10px 5px;
}
header h1 {
font-size: 1.5em;
}
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>📊 Liste des Clients</h1>
<p>Application de démonstration Node.js + MySQL</p>
<div class="stats">
<div class="stat-card">
<strong id="total-clients">0</strong> clients
</div>
</div>
</header>
<main>
<div id="loading" class="loading">
⏳ Chargement des données...
</div>
<div id="error" class="error" style="display:none;"></div>
<table id="clients-table" style="display:none;">
<thead>
<tr>
<th>ID</th>
<th>Nom</th>
<th>Email</th>
<th>Date création</th>
</tr>
</thead>
<tbody>
<!-- Les données seront insérées ici par JavaScript -->
</tbody>
</table>
</main>
</div>
<script>
// Fonction pour charger et afficher les clients
async function chargerClients() {
const loading = document.getElementById('loading');
const errorDiv = document.getElementById('error');
const table = document.getElementById('clients-table');
const tbody = table.querySelector('tbody');
try {
// Appel API pour récupérer les données
const response = await fetch('/api/clients');
if (!response.ok) {
throw new Error(`Erreur HTTP: ${response.status}`);
}
const result = await response.json();
if (!result.success) {
throw new Error(result.message);
}
const clients = result.data;
// Afficher le nombre total de clients
document.getElementById('total-clients').textContent = clients.length;
// Vider le tableau
tbody.innerHTML = '';
// Remplir le tableau avec les données
clients.forEach((client, index) => {
const row = document.createElement('tr');
// Formater la date
const date = new Date(client.date_creation);
const dateFormatee = date.toLocaleDateString('fr-FR', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
row.innerHTML = `
<td><span class="badge">#${client.id}</span></td>
<td><strong>${escapeHtml(client.nom)}</strong></td>
<td>${escapeHtml(client.email)}</td>
<td>${dateFormatee}</td>
`;
tbody.appendChild(row);
});
// Afficher le tableau et masquer le loading
loading.style.display = 'none';
table.style.display = 'table';
} catch (error) {
console.error('❌ Erreur:', error);
loading.style.display = 'none';
errorDiv.textContent = `⚠️ Erreur: ${error.message}`;
errorDiv.style.display = 'block';
}
}
// Fonction pour échapper le HTML et prévenir les attaques XSS
function escapeHtml(text) {
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return text.replace(/[&<>"']/g, m => map[m]);
}
// Charger les données au chargement de la page
document.addEventListener('DOMContentLoaded', chargerClients);
</script>
</body>
</html>
Étape 6 : Tester l'application Node.js MySQL
Maintenant que tout est configuré, il est temps de tester votre application. Assurez-vous que votre serveur MySQL est en cours d'exécution, puis démarrez le serveur Node.js :
node server.js
Vous devriez voir les messages suivants dans votre console :
✅ Connecté à la base de données MySQL ! 🚀 Serveur démarré sur http://localhost:3000
Ouvrez votre navigateur et accédez à http://localhost:3000. Vous verrez la liste des clients affichée dans un tableau responsive avec un design moderne.
Tests à effectuer :
- Vérifiez que les données s'affichent correctement
- Testez la responsivité sur différentes tailles d'écran
- Ouvrez la console du navigateur pour vérifier qu'il n'y a pas d'erreurs
- Testez l'API directement en accédant à
http://localhost:3000/api/clients
Bonnes pratiques et sécurité
Lors du développement d'applications Node.js avec MySQL, il est crucial de suivre ces bonnes pratiques de sécurité :
- Requêtes paramétrées : Utilisez toujours des paramètres (
?) pour éviter les injections SQL - Variables d'environnement : Ne stockez jamais les identifiants dans le code source
- Pool de connexions : Utilisez un pool plutôt que des connexions individuelles pour de meilleures performances
- Gestion des erreurs : Implémentez une gestion robuste des erreurs avec try/catch
- Validation des données : Validez toujours les entrées utilisateur côté serveur
- HTTPS : Utilisez HTTPS en production pour chiffrer les communications
- Limites de requêtes : Implémentez une pagination pour les grandes quantités de données
Aller plus loin avec Node.js et MySQL
Ce tutoriel vous a montré les bases de l'utilisation de Node.js avec MySQL. Voici quelques pistes pour améliorer votre application :
- Ajouter des opérations CRUD complètes : Créer, lire, mettre à jour et supprimer des clients
- Implémenter l'authentification : Ajouter un système de login avec JWT ou sessions
- Utiliser un ORM : Essayer Sequelize ou TypeORM pour simplifier les requêtes
- Ajouter la pagination : Limiter le nombre de résultats par page
- Implémenter la recherche : Permettre aux utilisateurs de rechercher des clients
- Ajouter la validation : Utiliser des bibliothèques comme Joi ou express-validator
- Optimiser les performances : Ajouter des index MySQL, mettre en cache les requêtes fréquentes
Conclusion
Félicitations ! Vous avez créé une application complète qui connecte Node.js à MySQL et affiche les données dans une interface web responsive et moderne. Ce projet vous a permis d'apprendre :
- Comment configurer une connexion MySQL dans Node.js avec mysql2
- L'utilisation d'Express.js pour créer un serveur web et des API REST
- Les bonnes pratiques de sécurité (variables d'environnement, requêtes paramétrées)
- La gestion asynchrone avec async/await et les Promises
- L'affichage dynamique de données avec JavaScript moderne
Vous pouvez maintenant étendre ce projet en ajoutant des fonctionnalités supplémentaires comme la gestion complète des clients (ajout, modification, suppression), l'authentification utilisateur, ou encore la mise en place d'un système de recherche avancé.