Programmation avec Node.js, Express·js et MongoDB
JavaScript côté serveur
2e edition
Éric Sarrion
Éditions Eyrolles
Première partie
Le coeur de Node.js1
Chapitre 1
Introduction à Node.js
3
Installation de Node.js3
Un premier programme avec Node.js4
Principe de fonctionnement de Node.js5
Utiliser REPL6
Chapitre 2
Gestion des modules
7
Inclusion de modules dans un fichier JavaScript7
Définir le module dans un fichier JavaScript externe8
Définir le module par un ensemble de fichiers situés dans un même répertoire9
Utiliser le fichier index.js10
Utiliser le répertoire node _ modules11
Utiliser un module standard défini par Node12
Télécharger de nouveaux modules avec npm15
Ecrire un module proposant de nouvelles fonctionnalités20
Cas particulier : un module composé d'une fonction principale23
L'objet module défini par Node24
Mise en cache des modules27
Visibilité des variables28
Le fichier package.json29
Chapitre 3
Gestora des événements
31
Pourquoi utiliser la classe events.EventEmitter ?31
Créer un objet de la classe events.EventEmitter32
Gérer des événements sur un objet de classe events.EventEmitter33
Utiliser les méthodes addListener() et emit()34
Utiliser plusieurs fois la méthode addListener()35
Supprimer un gestionnaire d'événements37
Supprimer tous les gestionnaires pour un événement38
Transmettre des paramètres lors de l'événement39
Créer une classe dérivant de events.EventEmitter41
Implémentation d'une classe Server simple41
Créer plusieurs serveurs associés à la classe Server42
Amélioration du programme44
Méthodes définies dans la classe events.EventEmitter45
Chapitre 4
Méthodes utilitaires
47
Gestion de l'affichage à l'écran : objet console47
Utiliser console.log()48
Utiliser console.time(label) et console.timeEnd(label)49
Utiliser console.dir(obj)50
Fonctions générales : module util52
Formatage de chaîne de caractères52
Inspecter des objets avec util.inspect()53
Héritage de classes55
Méthodes booléennes56
Gestion des URL : module url57
Utiliser url.parse()58
Utiliser url.resolve()59
Gestion des requêtes : module querystring60
Gestion des chemins : module path61
Gestion d'octets : classe Buffer64
Créer un objet de classe Buffer64
Modifier un buffer67
Copier et découper un buffer69
Changer l'encodage d'une chaîne au moyen d'un buffer70
Connaître la taille d'une chaîne de caractères en octets72
Gestion des timers73
Chapitre 5
Gestion des streams
75
Créer un stream en lecture76
Utiliser l'événement data sur le stream77
Définir la méthode _read() sur le stream80
Indiquer l'encodage pour les paquets lus sur le stream82
Utiliser la méthode read() sur le stream plutôt que l'événement data83
Connaître la fin du stream en lecture avec l'événement end85
Exemple de gestion d'un stream en lecture85
Utiliser les méthodes pause() et resume()87
Créer un stream en écriture88
Utiliser la méthode write() sur le stream90
Définir la méthode _write() sur le stream90
Indiquer la fin d'un stream en écriture92
Connecter un stream en lecture sur un stream en écriture93
Exemple de stream en écriture94
Créer un stream en lecture et écriture95
Chapitre 6
Gestion des fichiers
97
Gestion synchrone et gestion asynchrone97
Gestion synchrone97
Gestion asynchrone98
Quelle gestion (synchrone ou asynchrone) choisir ?99
Ouvrir et fermer un fichier100
Ouvrir un fichier100
Fermer un fichier101
Lire un fichier101
Lecture du fichier en totalité102
Lecture partielle du fichier103
Écrire dans un fichier105
Écraser le contenu du fichier105
Ajouter des octets à la fin du fichier105
Dupliquer un fichier107
Supprimer un fichier107
Renommer un fichier ou un répertoire109
Créer ou supprimer un répertoire109
Créer un répertoire109
Supprimer un répertoire111
Lister tous les fichiers d'un répertoire111
T ester l'existence d'un fichier ou d'un répertoire112
Obtenir des informations sur un fichier ou un répertoire113
Relier les fichiers et les streams114
Copier un fichier dans un autre au moyen d'un stream115
Copier dans un fichier les caractères entrés au clavier115
Chapitre 7
Gestion des processus
117
Exécuter un processus grâce à la méthode exec() du module child_process117
Exécuter une commande système en tant que nouveau processus118
Exécuter un fichier Node en tant que nouveau processus119
Exécuter un processus grâce à la méthode spawn() du module child_process120
Exécuter un fichier Node en tant que nouveau processus121
Gérer les cas d'erreur dans le processus fils122
Communication entre le processus père et le processus fils123
Chapitre 8
Gestion des connexions TCP
127
Principe d'une connexion TCP127
Le programme Telnet128
Créer un serveur TCP129
Utiliser la méthode net.createServer()129
Autre forme de la méthode net.createServer()131
Utiliser le paramètre socket pour indiquer au client qu'il est connecté132
Utiliser l'événement listening pour indiquer que le serveur a démarré133
Méthodes associées à un serveur TCP134
Événements associés à un serveur TCP137
Créer un client TCP139
Utiliser la méthode net.connect(port) .140
Dissocier le programme du client et celui du serveur141
Gérer la déconnexion d'un client TCP au serveur142
Communication entre le serveur TCP et un client TCP143
Gérer le flux entre le serveur et le client144
Gérer l'arrêt du serveur145
Exemple : communication entre plusieurs clients TCP via un serveur TCP147
Chapitre 9
Gestion des connexions UDP
153
Principe d'une connexion UDP153
Le programme Netcat154
Créer un serveur UDP155
Utiliser la méthode dgram.createSocket()155
Autre forme de la méthode dgram.createSocket()157
Utiliser l'événement listening pour indiquer que le serveur a démarré157
Connexion/déconnexion du client ou du serveur158
Créer un client UDP159
Utiliser la méthode dgram.createSocket()159
Envoyer un message vers le serveur avec la méthode send()159
Permettre au serveur de répondre au client161
Dissocier le programme du client et celui du serveur162
Événements associés à un objet de classe dgram.Socket164
Méthodes associées à un objet de classe dgram.Socket164
Exemple : communication entre deux sockets UDP166
Chapitre 10
Gestion des connexions HTTP
169
Créer un serveur HTTP169
Utiliser la méthode http.createServer()170
Autre forme de la méthode http.createServer()171
Objet associé au paramètre request172
Objet associé au paramètre response175
Envoyer un fichier statique en réponse au navigateur176
Utiliser plusieurs fichiers statiques dans la réponse178
Envoyer un en-tête HTTP dans la réponse au navigateur179
Événement associé à l'objet response182
Evénements associés au serveur182
Méthodes définies sur l'objet server183
Créer un client HTTP183
Utiliser la méthode http.request()183
Utiliser l'événement response plutôt que la fonction de callback186
Utiliser l'événement end sur le stream en lecture187
Envoyer les informations reçues dans un fichier189
Utiliser la méthode http.get()189
Transmettre des données vers le serveur HTTP190
Dissocier le programme du client et celui du serveur195
Transmettre un fichier vers le serveur (upload de fichier)197
Chapitre 11
Utiliser les web sockets avec socket.io
201
Installer le module socket.io201
Communication du client vers le serveur202
Programme côté client202
Programme côté serveur203
Exécution du programme205
Déconnexion d'un client206
Communication du serveur vers le client207
Programme côté client207
Programme côté serveur208
Exécution du programme209
Diffuser des informations à plusieurs clients210
Transmission des informations entre le client et le serveur211
Chapitre 12
Gestion asynchrone
213
Utiliser le fonctionnement traditionnel213
Utiliser les promesses215
Utiliser la méthode then()216
Utiliser la méthode catch()218
Utiliser la méthode finally()219
Transmission de paramètres dans resolve()221
Enchaînement de plusieurs timers222
Utiliser async/await223
Utiliser l'instmction async223
Utiliser l'instruction await225
Deuxième partie
Construire des applications web avec le framework Express229
Chapitre 13
Introduction au module Connect
231
Installer le module Connect231
Créer un serveur HTTP sans utiliser Connect232
Créer un serveur HTTP en utilisant Connect233
Effectuer plusieurs actions lors du traitement d'une requête HTTP (sans utiliser Connect)234
Effectuer plusieurs actions lors du traitement d'une requête HTTP (en utilisant Connect)236
Définir et utiliser un middleware238
Créer le middleware dans le programme de l'application239
Créer le middleware dans un fichier externe241
Transmettre des paramètres au middleware242
Paramètres optionnels dans un middleware243
Effectuer plusieurs appels à un middleware243
Chaînage des méthodes dans Connect244
Cas d'erreurs dans les middlewares245
Chapitre 14
Utiliser les middlewares liés à Connect
249
Middleware morgan : afficher les informations dans les logs250
Middleware serve-static : afficher les fichiers statiques253
Middleware body-parser : récupérer les données transmises dans l'en-tête255
Middleware method-override : gérer les requêtes REST257
Introduction à REST258
Utiliser le middleware method-override258
Chapitre 15
Introduction au framework Express
263
Installer le framework Express263
Créer une application web avec Express265
Architecture d'une application Express268
Le fichier ./bin/www exécuté par npm start268
Le fichier app.js270
Autres répertoires et fichiers créés par Express272
Le modèle MVC272
Chapitre 16 .
Routage des requêtes avec Express
275
Qu'est-ce qu'une route ?275
Analyse des routes déjà présentes dans app.js275
Ajout d'une nouvelle route dans app.js (première façon)278
Ajout d'une nouvelle route dans app.js (deuxième façon)278
Utiliser la route en tant que middleware280
Chaîner les méthodes get() entre elles281
Définir le type de requête directement dans le fichier app.js282
Architecture REST .283
Méthodes liées aux types de requêtes HTTP283
Utiliser le middleware method-override dans Express284
Utiliser l'outil Postman287
Définir un middleware valable pour tous les types de routes288
Définir l'URL dans les routes289
URL définie sous forme de chaîne de caractères290
URL définie sous forme d'expression régulière290
URL définie en utilisant des noms de variables293
Utiliser plusieurs noms de variables dans l'URL294
Noms de variables optionnels295
Vérifier les valeurs possibles d'un nom de variable297
Ordre de priorité des routes297
Chapitre 17
Envoyer la réponse du serveur
299
Retourner un code HTTP299
Les différentes catégories de code HTTP300
Utiliser la méthode res.status(statusCode)302
Retourner un en-tête au navigateur304
Retourner le corps de la réponse305
Retourner du code HTML encodé en UTF-8306
Retourner du texte simple307
Retourner du JSON307
Retourner des fichiers statiques308
Retourner des fichiers dynamiques309
Retourner une vue310
Permettre un affichage lisible du code HTML de la page314
Rediriger vers une autre URL315
Chapitre 18
Objets app, req et res utilisés par Express
317
Objet app : gérer l'application Express317
Gérer le format des variables dans les URL318
Récupérer et modifier le code HTML généré par une vue322
Partager des objets avec les vues325
Objet req : gérer la requête reçue327
Récupérer les informations transmises par les utilisateurs327
Récupérer les informations sur la route utilisée328
Objet res : gérer la réponse à envoyer330
Chapitre 19
Créer Ses vues avec EJS
331
Installer EJS331
Une première vue avec EJS332
Transmettre des paramètres à la vue334
Cas pratique : utiliser plusieurs vues dans une application338
Cinématique de l'application338
Programmes de l'application341
Ajouter des styles dans les vues348
Utiliser la base de données MongoDB avec Node351
Chapitre 20
Introduction à MongoDB
353
Installer MongoDB353
Documents et collections355
Définir un document355
Définir une collection356
Utiliser l'exécutable mongo357
Exécution dans un shell357
Exécution dans un fichier JavaScript358
Établir une connexion à la base de données359
Créer des documents361
Rechercher des documents363
Rechercher tous les documents de la collection364
Spécifier une condition AND365
Utiliser $gt, $it ou $in dans une condition366
Spécifier une condition OR368
Utiliser les conditions AND et OR simultanément369
Rechercher selon l'existence ou le type d'un champ, dans un document370
Rechercher l'existence d'un champ dans un document avec $exists370
Rechercher selon un type de champ avec $type374
Rechercher à l'aide d'une expression JavaScript avec $where376
Rechercher dans des sous-documents379
Rechercher dans des tableaux382
Trier les documents lors d'une recherche386
Indiquer les champs à retourner lors d'une recherche388
Compter le nombre de documents trouvés lors d'une recherche390
Rechercher le premier document qui satisfait une recherche391
Mettre à jour des documents392
Utiliser la méthode save(document)393
Utiliser la méthode update(query, update, options)396
Mettre à jour la totalité d'un document397
Mettre à jour partiellement un document398
Mettre à jour plusieurs documents simultanément400
Supprimer des documents401
Actions globales sur une collection404
Actions globales sur une base de données405
Chapitre 21
Introduction au module Mongoose
407
Installer le module Mongoose407
Etablir une connexion à la base de données avec Mongoose408
Utiliser les schémas et les modèles410
Définir un schéma411
Définir un modèle412
Chapitre 22
Créer des documents
415
Créer un document en utilisant la méthode d'instance save()415
Insérer un document dans la collection415
Récupérer la liste des documents de la collection :416
Insérer un document, puis récupérer la liste des documents de la collection418
Créer un document en utilisant la méthode de classe create421
Créer des sous-documents423
Chapitre 23
Rechercher des documents
427
Utiliser la méthode find(conditions, callback)427
Exemples de recherche428
Écriture des conditions de recherche432
Utiliser la méthode find(conditions)433
Méthodes utilisables dans la classe mongoose. Query439
Utiliser la méthode findOne()440
Utiliser la méthode findById()441
Utiliser la méthode countDocuments()441
Utiliser countDocuments(conditions, callback)442
Utiliser countDocuments(callback)444
Chapitre 24
Modifier des documents
447
Utiliser la méthode de classe updateOne() ou updateMany()447
Mettre à jour un seul document avec updateOne()448
Mettre à jour plusieurs documents avec updateMany()450
Suppression de champs dans les documents.451
Utiliser la méthode save()453
Chapitre 25
Supprimer des documents
455
Utiliser la méthode de classe deleteOne() ou deleteMany()455
Utiliser la méthode d'instance remove()457
Chapitre 26
Valider les données
459
Préparation de la base de données459
Valider un premier document460
Afficher un message d'erreur si la validation échoue462
Validations par défaut de Mongoose465
Créer sa propre validation468
Chapitre 27
Utiliser le concept de population
473
Indiquer les relations dans les schémas473
Ajout de documents dans les collections475
Recherche de documents dans les collections478
Utiliser la méthode populate()483
Utiliser la méthode populate() sur l'objet mongoose.Query483
Utiliser la méthode populate() sur le modèle484
Utiliser la méthode populate() sur un document486
Chapitre 28
Utiliser les middlewares dans Mongoose
489
Utiliser les pre middlewares490
Méthode pre() définissant un middleware490
Utiliser un pre middleware lors de la sauvegarde d'un document490
Utiliser un pre middleware lors de la validation d'un document492
Utiliser un pre middleware lors de la suppression d'un document494
Utiliser le mot-clé this dans un pre middleware495
Utiliser les post middlewares496
Méthode post() définissant un middleware497
Utiliser un post middleware497
Chapitre 29
Construction d'une application client serveur avec Express et MongoDB
501
Quatrième partie
Quelques modules Node (très) utiles509
Chapitre 30
Le module async
511
Installer le module async511
Méthodes agissant sur les tableaux de données512
Méthode each()512
Méthode eachSeries()516
Méthode map()517
Méthode mapSeries()521
Méthode sortBy()522
Méthodes agissant sur l'enchaînement des fonctions de callback525
Méthode series()525
Méthode parallel()530
Méthode parallelLimit()532
Méthode waterfall()533
Chapitre 31
Le module supervisor
537
Installer le module supervisor537
Utiliser le module supervisor538
Chapitre 32
Le module mongo-express
541
Installer le module mongo-express541
Utiliser le module mongo-express542
Index
545