Définir le rôle du serveur
Le back-end offre à l’interface un endroit fiable où demander un traitement. Avec Node.js et Express, vous découvrirez comment une route reçoit une requête, applique la logique de l’application et renvoie une réponse utile. Une frontière claire sépare la présentation des règles et du traitement des données.
Donner une place durable aux données
MongoDB introduit le stockage de données orienté document. Il faut déterminer quelles informations vont ensemble, comment les enregistrements se relient à l’application et comment le serveur les lit ou les met à jour. Une couche de données bien pensée rend l’application utile au-delà d’une seule session navigateur.
Relier l’identité aux actions protégées
L’authentification fait partie du parcours applicatif, pas seulement d’un écran de connexion. JWT et Google OAuth interviennent différemment : l’un représente une session authentifiée, l’autre permet d’établir son identité via Google. Cette étape relie les routes, les données et l’identité dans une application dynamique.
Du concept au code qui fonctionne
Ces extraits montrent comment les notions de chaque niveau prennent forme dans un projet. Ils servent de points de départ à lire, questionner, adapter et tester — pas de code à copier sans le comprendre.
Valider à la frontière du serveur
La route récupère l’identifiant de l’atelier dans l’URL et valide les données avant toute écriture. Elle distingue les entrées invalides, l’atelier absent et la création réussie avec des statuts HTTP adaptés.
router.post("/workshops/:id/registrations", async (req, res) => {
const { name, email } = req.body;
const workshopId = req.params.id;
if (!name?.trim() || !/^\S+@\S+\.\S+$/.test(email ?? "")) {
return res.status(400).json({ error: "Name and valid email required." });
}
const workshop = await workshops.findOne({ _id: workshopId });
if (!workshop) return res.status(404).json({ error: "Workshop not found." });
const registration = await registrations.insertOne({
workshopId,
name: name.trim(),
email: email.toLowerCase(),
createdAt: new Date(),
});
return res.status(201).json({ id: registration.insertedId });
});Isoler la persistance dans un dépôt
Le dépôt prend en charge les opérations MongoDB et fournit une interface réduite au reste de l’application. La route reste lisible et le stockage peut évoluer ou être testé depuis un point unique.
export function createRegistrationRepository(db) {
const registrations = db.collection("registrations");
return {
async create(input) {
const result = await registrations.insertOne({
workshopId: input.workshopId,
name: input.name.trim(),
email: input.email.toLowerCase(),
status: "pending",
createdAt: new Date(),
});
return { id: result.insertedId.toString(), status: "pending" };
},
findForWorkshop(workshopId) {
return registrations.find({ workshopId }).toArray();
},
};
}Lisez, puis adaptezModifiez une exigence, prévoyez le résultat, puis exécutez le code pour vérifier. En revue, expliquez le compromis choisi et une amélioration que vous apporteriez ensuite.