Public cible
Débutants, étudiants et professionnels qui souhaitent acquérir une pratique structurée dans ce domaine.
Construire un back-end Node.js/Express avec API, authentification, communications temps réel, base de données, sécurité et intégration continue.
Débutants, étudiants et professionnels qui souhaitent acquérir une pratique structurée dans ce domaine.
Comprendre les notions essentielles et les appliquer dans un projet vérifiable.
Aucune connaissance préalable n’est strictement obligatoire ; les prérequis détaillés sont précisés dans les ateliers.
Tous niveaux
La validation repose sur les évaluations actives et les livrables pratiques du cours.
Un ordinateur, un navigateur et les outils indiqués dans le premier atelier sont suffisants pour commencer.
Implémenter une API ou un service backend en conditions réelles.
Obligatoire ConsulterVérifier les notions Node.js, API, sécurité et temps réel.
Obligatoire ConsulterDéployer une application complète avec tests et documentation.
Livrables :
Implémenter une API ou un service backend en conditions réelles.
Obligatoire ConsulterVérifier les notions Node.js, API, sécurité et temps réel.
Obligatoire ConsulterDéployer une application complète avec tests et documentation.
Livrables :
Implémenter une API ou un service backend en conditions réelles.
Obligatoire ConsulterVérifier les notions Node.js, API, sécurité et temps réel.
Obligatoire ConsulterDéployer une application complète avec tests et documentation.
Livrables :
Implémenter une API ou un service backend en conditions réelles.
Obligatoire ConsulterVérifier les notions Node.js, API, sécurité et temps réel.
Obligatoire ConsulterDéployer une application complète avec tests et documentation.
Livrables :
Implémenter une API ou un service backend en conditions réelles.
Obligatoire ConsulterVérifier les notions Node.js, API, sécurité et temps réel.
Obligatoire ConsulterDéployer une application complète avec tests et documentation.
Livrables :
Implémenter une API ou un service backend en conditions réelles.
Obligatoire ConsulterVérifier les notions Node.js, API, sécurité et temps réel.
Obligatoire ConsulterDéployer une application complète avec tests et documentation.
Livrables :
21 heures
Avant de suivre ce cours, il est recommandé d'avoir une bonne compréhension des concepts fondamentaux de la programmation et d'avoir déjà suivi le tronc commun de E3, qui couvre les bases de la programmation JavaScript, HTML, et CSS ainsi que les concepts de bases de données.
Lorsque vous démarrez un nouveau projet Node.js, la première étape consiste à initialiser le projet. Cela se fait généralement en utilisant npm (Node Package Manager), qui est livré avec Node.js.
mkdir (Make Directory) pour créer un nouveau répertoire où votre projet Node.js sera stocké.cd (Change Directory) pour naviguer vers le répertoire que vous venez de créer.npm init. Cela lancera un assistant interactif qui vous guidera dans la création d'un fichier package.json pour votre projet.npm init vous posera plusieurs questions sur votre projet, telles que le nom du projet, sa version, sa description, etc. Vous pouvez répondre à ces questions en fonction des besoins de votre projet.Une fois que vous avez initialisé votre projet Node.js, il est important de le structurer de manière appropriée en suivant les bonnes pratiques. Une bonne structure de projet facilite la gestion et la maintenance de votre code, ainsi que la collaboration avec d'autres développeurs.
package.json, README.md, .gitignore, etc.
src/ et lib/ :
Pour le code source principal et les bibliothèques ou modules réutilisables.
tests/ pour les fichiers de test unitaire ou de test d'intégration.
public/ pour les images, fichiers CSS, fichiers JavaScript frontaux, etc.
config/ pour les fichiers de configuration de l'application.
routes/ et controllers/ pour organiser les fichiers de routage et de contrôleurs.
projet-nodejs/
│
├── src/
│ ├── controllers/
│ │ ├── authController.js
│ │ ├── chatController.js
│ │ └── ...
│ ├── routes/
│ │ ├── authRoutes.js
│ │ ├── chatRoutes.js
│ │ └── ...
│ ├── models/
│ │ ├── user.js
│ │ ├── message.js
│ │ └── ...
│ ├── services/
│ │ ├── authService.js
│ │ ├── chatService.js
│ │ └── ...
│ └── app.js
│
├── tests/
│ ├── auth.test.js
│ ├── chat.test.js
│ └── ...
│
├── config/
│ ├── config.js
│ ├── database.js
│ └── ...
│
├── public/
│ ├── css/
│ ├── js/
│ └── ...
│
├── package.json
├── package-lock.json
└── README.md
Express.js est un framework web minimaliste et flexible pour Node.js qui facilite la création d'applications web robustes et évolutives. Voici comment mettre en place un serveur Express pour gérer les requêtes HTTP entrantes et définir des routes pour les différentes fonctionnalités de l'application :
Avant de commencer, assurez-vous d'avoir Express installé dans votre projet. Si ce n'est pas déjà le cas, vous pouvez l'installer en utilisant npm (Node Package Manager) avec la commande suivante dans votre terminal :
npm install express
Dans votre fichier app.js (ou tout autre fichier principal de votre application), importez Express en tant que module :
const express = require('express');
Créez une instance de l'application Express en appelant la fonction express() :
const app = express();
Utilisez le middleware Express pour configurer le comportement de votre application. Par exemple, vous pouvez définir des middleware pour gérer les requêtes de journalisation, analyser les corps de requête JSON, etc.
Utilisez la méthode de routage d'Express pour définir des routes pour les différentes fonctionnalités de votre application. Chaque route peut avoir un ou plusieurs gestionnaires de requêtes qui sont appelés lorsque la route est atteinte. Par exemple :
app.get('/', (req, res) => { res.send('Bienvenue sur mon application!'); });
Enfin, démarrez le serveur en écoutant les connexions sur un port spécifique. Par exemple :
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Serveur démarré sur le port ${PORT}`);
});
Avec ces étapes, vous avez mis en place un serveur Express pour votre application Node.js. Vous pouvez maintenant définir des routes supplémentaires et des gestionnaires de requêtes pour implémenter les fonctionnalités de votre application, telles que l'authentification, la gestion des utilisateurs, la gestion des messages, etc.
Une promesse représente une valeur qui peut être disponible immédiatement, dans le futur ou jamais. Elle peut être dans l'un des trois états suivants :
Les promesses sont particulièrement utiles pour gérer les opérations asynchrones, qu'elles soient IO-bound ou CPU-bound. Elles permettent d'attendre la résolution d'une ou plusieurs promesses avant de poursuivre l'exécution du code.
const fetchData = () => {
return new Promise((resolve, reject) => {
// Effectuer une opération asynchrone, par exemple, une requête HTTP
fetch('https://api.example.com/data')
.then(response => {
if (response.ok) {
resolve(response.json());
} else {
reject(new Error('Erreur lors de la récupération des données'));
}
})
.catch(error => {
reject(error);
});
});
};
// Utilisation de la promesse
fetchData()
.then(data => {
console.log('Données récupérées avec succès :', data);
})
.catch(error => {
console.error('Erreur lors de la récupération des données :', error);
});
En plus de comprendre les états des promesses, il est important de maîtriser certaines techniques courantes pour travailler avec les promesses.
Cette méthode prend un tableau de promesses en entrée et retourne une nouvelle promesse qui est résolue une fois que toutes les promesses du tableau sont résolues, ou rejetée dès qu'une seule des promesses est rejetée.
Supposons que vous ayez une application où vous devez effectuer plusieurs appels asynchrones et traiter les résultats de manière synchrone.
// Fonction pour simuler un appel asynchrone
const asyncFunction = (id, delay) => {
return new Promise((resolve, reject) => {
// Simuler une opération asynchrone avec un délai donné
setTimeout(() => {
resolve(`Résultat de l'appel asynchrone ${id}`);
}, delay);
});
};
// Fonction principale asynchrone pour gérer les appels asynchrones de manière synchrone
const handleAsyncCalls = async () => {
try {
// Attendre la résolution de plusieurs appels asynchrones de manière synchrone
const result1 = await asyncFunction(1, 2000); // Appel asynchrone 1 avec un délai de 2 secondes
console.log(result1);
const result2 = await asyncFunction(2, 3000); // Appel asynchrone 2 avec un délai de 3 secondes
console.log(result2);
const result3 = await asyncFunction(3, 1000); // Appel asynchrone 3 avec un délai de 1 seconde
console.log(result3);
} catch (error) {
console.error('Une erreur s\'est produite :', error);
}
};
// Appel de la fonction principale asynchrone
handleAsyncCalls();
Utilisez async/await lorsque vous avez besoin d'écrire du code asynchrone de manière synchrone et que les appels asynchrones doivent être exécutés séquentiellement ou lorsque la gestion des erreurs est importante.
Promise.all, Promise.race et async/await sont des outils puissants pour gérer l'asynchronisme en JavaScript. Promise.all est idéal pour attendre la résolution de plusieurs promesses en parallèle, Promise.race est utile pour réagir rapidement à la première réponse disponible, et async/await est pratique pour écrire du code asynchrone de manière synchrone. Choisissez la technique qui correspond le mieux à vos besoins en fonction de la situation spécifique.
Cette méthode prend un tableau de promesses en entrée et retourne une nouvelle promesse qui est résolue ou rejetée dès que l'une des promesses du tableau est résolue ou rejetée, en fonction de celle qui se produit en premier.
Supposons que vous ayez une application où vous avez besoin d'afficher du contenu provenant de différentes sources, mais vous voulez afficher le contenu dès qu'une source répond en premier.
// Fonction pour récupérer du contenu à partir d'une source
const getContentFromSource = (source, delay) => {
return new Promise((resolve, reject) => {
// Simuler la récupération de contenu depuis une source avec un délai donné
setTimeout(() => {
resolve(`Contenu de ${source}`);
}, delay);
});
};
// URLs des sources de contenu et délais associés
const sources = {
'Source A': 2000, // Délai de 2 secondes
'Source B': 3000, // Délai de 3 secondes
'Source C': 1500 // Délai de 1.5 secondes
};
// Récupérer le contenu de la première source à répondre
Promise.race(Object.entries(sources).map(([source, delay]) => getContentFromSource(source, delay)))
.then(content => {
console.log('Le contenu de la première source à répondre est :', content);
})
.catch(error => {
console.error('Une erreur s\'est produite :', error);
});
Ces mots-clés permettent d'écrire du code asynchrone de manière synchrone, en utilisant des fonctions asynchrones. L'opérateur await permet d'attendre la résolution d'une promesse à l'intérieur d'une fonction asynchrone.
Supposons que vous ayez une application où vous avez besoin d'afficher du contenu provenant de différentes sources, mais vous voulez afficher le contenu dès qu'une source répond en premier.
// Fonction pour récupérer du contenu à partir d'une source
const getContentFromSource = (source, delay) => {
return new Promise((resolve, reject) => {
// Simuler la récupération de contenu depuis une source avec un délai donné
setTimeout(() => {
resolve(`Contenu de ${source}`);
}, delay);
});
};
// URLs des sources de contenu et délais associés
const sources = {
'Source A': 2000, // Délai de 2 secondes
'Source B': 3000, // Délai de 3 secondes
'Source C': 1500 // Délai de 1.5 secondes
};
// Récupérer le contenu de la première source à répondre
Promise.race(Object.entries(sources).map(([source, delay]) => getContentFromSource(source, delay)))
.then(content => {
console.log('Le contenu de la première source à répondre est :', content);
})
.catch(error => {
console.error('Une erreur s\'est produite :', error);
});
En comprenant ces concepts et en maîtrisant ces techniques, vous serez en mesure de gérer efficacement l'asynchronisme dans vos applications JavaScript et d'écrire un code plus propre et plus maintenable.
Le projet de création d'un chat vise à fournir une plateforme de communication en temps réel où les utilisateurs peuvent échanger des messages de manière instantanée. Les principaux objectifs de ce projet sont les suivants :
Pour mener à bien ce projet, les étudiants devront respecter les exigences suivantes :
Les fonctionnalités principales attendues dans ce projet de création d'un chat comprennent :
En intégrant ces fonctionnalités, le projet vise à créer une expérience de chat immersive et intuitive pour les utilisateurs, tout en consolidant les compétences techniques des développeurs dans le domaine du développement Full Stack.
Express.js est un framework web pour Node.js qui simplifie la création d'applications web en fournissant des fonctionnalités robustes pour la gestion des routes, des requêtes HTTP et des vues. Dans le cadre de ce projet de création d'un chat, nous allons intégrer Express.js pour gérer les routes nécessaires et pour gérer l'authentification des utilisateurs à l'aide de middlewares.
Tout d'abord, nous devons installer Express.js dans notre projet. Cela peut être fait en utilisant npm (Node Package Manager). Assurez-vous d'avoir Node.js installé sur votre système, puis exécutez la commande suivante dans le répertoire de votre projet :
npm install express
Ensuite, nous allons configurer les routes nécessaires pour le chat. Cela inclut les routes pour l'authentification des utilisateurs, l'envoi et la réception de messages, la gestion des utilisateurs, etc. Voici un exemple de configuration de routes de base :
const express = require('express');
const router = express.Router();
// Route pour la page d'accueil du chat
router.get('/', (req, res) => {
res.render('chat'); // Afficher la vue du chat
});
// Route pour gérer l'envoi de messages
router.post('/messages', (req, res) => {
// Traitement pour envoyer un message
});
// Autres routes pour l'authentification, la gestion des utilisateurs, etc.
module.exports = router;
Nous utiliserons les middlewares Express.js pour gérer l'authentification des utilisateurs et les autorisations d'accès aux ressources. Par exemple, nous pouvons créer un middleware d'authentification pour vérifier si un utilisateur est connecté avant de lui permettre d'accéder à certaines routes :
// Middleware pour vérifier l'authentification de l'utilisateur
const authMiddleware = (req, res, next) => {
if (req.session && req.session.user) {
// L'utilisateur est connecté, continuer
next();
} else {
// L'utilisateur n'est pas connecté, rediriger vers la page de connexion
res.redirect('/login');
}
};
// Utilisation du middleware d'authentification pour protéger une route
router.get('/profile', authMiddleware, (req, res) => {
res.render('profile'); // Afficher la vue du profil de l'utilisateur
});
En intégrant Express.js de cette manière dans notre projet de chat, nous pouvons gérer efficacement les routes HTTP et les fonctionnalités d'authentification des utilisateurs, ce qui contribue à la création d'une application web robuste et sécurisée.
Un système d'authentification robuste est essentiel pour sécuriser l'accès au chat et protéger les données des utilisateurs. Nous allons mettre en œuvre un système d'authentification en utilisant un service d'authentification tel que Passport.js et en stockant et vérifiant les informations d'identification des utilisateurs dans une base de données MongoDB à l'aide de Mongoose.
Tout d'abord, nous devons installer Passport.js dans notre projet. Passport.js est un middleware d'authentification pour Node.js qui prend en charge différents schémas d'authentification, y compris les stratégies locales, OAuth, etc. Exécutez la commande suivante dans le répertoire de votre projet pour installer Passport.js :
npm install passport passport-local passport-local-mongoose
: Ensuite, nous allons configurer Passport.js dans notre application. Cela implique de définir une stratégie d'authentification locale, qui utilise les identifiants (nom d'utilisateur et mot de passe) stockés dans notre base de données MongoDB.
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const User = require('./models/user'); // Modèle utilisateur avec Mongoose
passport.use(new LocalStrategy(User.authenticate())); // Utilisation de la méthode d'authentification de Mongoose
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
Création de Routes d'Authentification : Nous devons créer des routes pour gérer l'authentification des utilisateurs, y compris les routes pour l'inscription, la connexion, la déconnexion, etc.
javascript
Copy code
// Route pour l'inscription d'un nouvel utilisateur
app.post('/register', (req, res) => {
User.register(new User({ username: req.body.username }), req.body.password, (err, user) => {
if (err) {
console.error('Erreur lors de l\'inscription :', err);
return res.redirect('/register');
}
passport.authenticate('local')(req, res, () => {
res.redirect('/chat');
});
});
});
// Route pour la connexion d'un utilisateur existant
app.post('/login', passport.authenticate('local', {
successRedirect: '/chat',
failureRedirect: '/login',
failureFlash: true
}));
// Route pour la déconnexion d'un utilisateur
app.get('/logout', (req, res) => {
req.logout();
res.redirect('/');
});
Nous utilisons Mongoose pour définir un schéma utilisateur et stocker les informations d'identification des utilisateurs dans une collection MongoDB.
const mongoose = require('mongoose');
const passportLocalMongoose = require('passport-local-mongoose');
const userSchema = new mongoose.Schema({
username: String,
password: String
});
userSchema.plugin(passportLocalMongoose); // Ajout des méthodes d'authentification à notre schéma utilisateur
module.exports = mongoose.model('User', userSchema);
En intégrant ces étapes, nous mettons en place un système d'authentification robuste dans notre projet de chat, garantissant que seuls les utilisateurs authentifiés ont accès aux fonctionnalités du chat.
Socket.io est une bibliothèque JavaScript qui permet une communication bidirectionnelle en temps réel entre le serveur et les clients. Nous allons l'intégrer dans notre projet de chat pour permettre une expérience de chat en temps réel et pour mettre en place un système de notifications pour informer les utilisateurs des nouveaux messages et d'autres événements importants.
Tout d'abord, nous devons installer Socket.io dans notre projet. Cela peut être fait en utilisant npm. Exécutez la commande suivante dans le répertoire de votre projet pour installer Socket.io :
npm install socket.io
Ensuite, nous allons configurer Socket.io dans notre application. Cela implique de créer une instance de serveur WebSocket et de gérer les événements de connexion et de déconnexion des clients.
const http = require('http');
const express = require('express');
const socketIo = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = socketIo(server);
io.on('connection', (socket) => {
console.log('Un client s\'est connecté');
// Gérer les événements liés aux messages
socket.on('chat message', (msg) => {
console.log('Message reçu :', msg);
// Diffuser le message à tous les autres clients connectés
socket.broadcast.emit('chat message', msg);
});
// Autres événements et fonctionnalités
});
server.listen(3000, () => {
console.log('Serveur en écoute sur le port 3000');
});
Avec Socket.io configuré, nous pouvons maintenant gérer les événements liés aux messages envoyés par les utilisateurs et diffuser ces messages à tous les autres clients connectés en temps réel.
// Client-side (HTML/JavaScript)
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();
// Envoyer un message au serveur lors de la soumission du formulaire
$('form').submit(() => {
socket.emit('chat message', $('#message').val());
$('#message').val('');
return false;
});
// Afficher les messages reçus du serveur
socket.on('chat message', (msg) => {
$('#messages').append($('<li>').text(msg));
});
</script>
Nous pouvons également utiliser Socket.io pour mettre en place un système de notifications afin d'informer les utilisateurs des nouveaux messages et d'autres événements importants.
// Serveur
io.on('connection', (socket) => {
// Envoyer une notification à tous les clients lorsqu'un nouvel utilisateur se connecte
socket.broadcast.emit('user connected', 'Un nouvel utilisateur s\'est connecté');
// Envoyer une notification à tous les clients lorsqu'un message est reçu
socket.on('chat message', (msg) => {
socket.broadcast.emit('new message', 'Nouveau message reçu');
});
// Autres événements et notifications
});
// Client-side
socket.on('new message', (notification) => {
// Afficher la notification de nouveau message à l'utilisateur
});
En intégrant ces étapes, nous mettons en place une communication bidirectionnelle en temps réel entre le serveur et les clients à l'aide de Socket.io. Cela permet à notre application de chat d'être réactive et de fournir des notifications instantanées aux utilisateurs pour les tenir informés des événements importants.
Postman et Postwoman sont des outils puissants pour tester des API et simuler les interactions frontend en envoyant des requêtes HTTP au serveur. Nous allons les utiliser pour configurer des requêtes HTTP et tester les différentes fonctionnalités de l'API backend que nous avons mises en place pour notre projet de chat.
En utilisant Postman ou Postwoman de cette manière, vous pouvez simuler les interactions frontend avec votre API backend et vous assurer que toutes les fonctionnalités sont correctement implémentées et fonctionnent comme prévu. Cela facilite le processus de développement et permet de détecter et de corriger rapidement les erreurs ou les problèmes potentiels.
Publié le 09/05/2025 — mis à jour le 15/10/2026