TP 1 : Installation et Manipulation de la BD NoSQL MongoDB - 2024-2025 PDF
Document Details
Uploaded by ViewableSquirrel2597
2024
Institut National des Postes et Télécommunications
Tags
Summary
This document is a past paper for a course on installing and manipulating NoSQL databases. The document covers installation, querying functionalities, and CRUD operations using MongoDB. The paper also explains how to use MongoDB with Node.js. The exam paper is for the year 2024.
Full Transcript
Institut National des Postes et Télécommunications 2024-2025 TP 1 : Installation et Manipulation de la BD NoSQL « MongoDB » Filière : ICCN, INE2 Encadré par : Pr. Dounia ZAIDOUNI Les objectifs du TP :...
Institut National des Postes et Télécommunications 2024-2025 TP 1 : Installation et Manipulation de la BD NoSQL « MongoDB » Filière : ICCN, INE2 Encadré par : Pr. Dounia ZAIDOUNI Les objectifs du TP : « Installation et Manipulation de MongoDB » sont les suivants : Installation et configuration de MongoDB sur VM Ubuntu. Examination des fonctionnalités de requêtage de MongoDB : Restauration d’un fichier «.bson » , Gestion des indexes, Recherche et tri des documents , Insertion des documents, Suppression des documents, Mise à jour des documents. Implémentation d’une application avec Node.js et MongoDB et réalisation des opérations CRUD : Create, Read, Update, Delete. 1) Installation et configuration de MongoDB : Installation et configuration : Pour installer MongoDB, deux types de paquets sont disponibles: le paquet fourni par la communauté ubuntu et le paquet fourni par la communauté mongodb. Le deuxième comporte la version la plus récente. Dans ce TP, nous allons installer le paquet fourni par la communauté ubuntu, pour cela, suivez les étapes suivantes : Étape 1 - Configuration du « apt Repository » : Tout d'abord, importez la clé GPK pour le « MongoDB apt Repository » sur votre système à l'aide de la commande suivante. wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | sudo apt-key add - Ensuite, créez le fichier liste /etc/apt/sources.list.d/mongodb-org-5.0.list pour ubuntu Focal (nous allons utiliser le repo de ubuntu Focal qui marche bien car jusqu’à maintenant MongoDB n'a pas de repo séparé pour la version Ubuntu Jammy), tapez : echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org- 5.0.list sudo apt update Étape 2 – Installation d’un paquet manquant : Il faut installer le paquet libssl1 pour installer MongoDB dans Ubuntu 22.04 sinon vous pouvez avoir une erreur lors de l’installation de MongoDB qui est la suivante : Pour éviter cette erreur, il faut télécharger le paquet libssl1.1_1.1.1f-1ubuntu2_amd64.deb de son repository officiel en tapant la commande : wget http://archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1. 1.1f-1ubuntu2_amd64.deb Ensuite installez le paquet en tapant la commande : sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2_amd64.deb Étape 2 – Installation de MongoDB sur une VM Ubuntu Utilisez les commandes suivantes pour installer MongoDB sur votre VM. Il installera également tous les packages dépendants requis pour MongoDB. $ sudo apt update $ sudo apt-get install -y mongodb-org Affichage de la version de MongoDB : Pour Afficher, la version de MongoDB que vous avez installé, tapez : $ mongod –version Gestion des services Mongod : 1- Activation et démarrage des services MongoDB : $ sudo systemctl enable mongod $ sudo systemctl start mongod 2- Affichage du statut de mongod : $ sudo systemctl status mongod 3- Arrêt et redémarrage des services MongoDB : Utilisez les commandes suivantes pour arrêter ou redémarrer le service MongoDB: $ sudo systemctl stop mongod $ sudo systemctl restart mongod 4- Test de la configuration : Connectez MongoDB à l'aide de la ligne de commande et exécutez certaines commandes de test pour vérifier le bon fonctionnement. Tapez dans le terminal la commande : $ mongo Puis tapez les commandes suivantes : > use mydb; > db.test.save( { zaidouni: 100 } ) > db.test.find() 2) Examination des fonctionnalités de requêtage de MongoDB Restauration d’un fichier «.bson » : Dans ce TP, nous allons utiliser les données stockées dans le fichier « moviedetails.bson » relatives aux informations sur plusieurs films. Récupérez ce fichier à partir de moodle, et déposez le dans /home/user/Documents. Ensuite, tapez la commande suivante pour restaurer ces données dans la BD mongoDB « cinema » : zaidouni@zaidouni:~/Documents$ mongorestore -d cinema -c films movieDetails.bson zaidouni@zaidouni:~/Documents$ mongo Pour tester la BD, tapez les commandes : > use cinema; > db.films.count() > db.films.findOne() Gestion des indexes : 1- Affichage des indexes : > db.films.getIndexes() 2- Création d’indexes : Voici un exemple de création d’un nouveau index « genre » dont le champ doit être obligatoirement présent : Remarque : La fonction ensureIndex() n’existe plus dans la version 5.0, il est remplacé par createIndex(). > db.films.createIndex({"genre": 1}, {"sparse": true}) Affichage des indexes : > db.films.getIndexes() 3- Suppression d’indexes : On peut supprimer un index avec la commande suivante : > db.collection.dropIndex(name) Pour savoir le nom de l'index à supprimer, utilisez la commande : db.collection.getIndexes() Tapez donc : > db.films.dropIndex("genre_1") Lorsqu'on recherche un document donné, il est possible de connaître la stratégie effective permettant à MongoDB de le retrouver grâce à la commande explain(). Dans ce cas MongoDB renvoie un document spécifique qui détaille la recherche avec notamment les indexes utilisés, le nombre de documents parcourus ou encore le temps global de la requête. C'est très pratique quand on veut optimiser ses requêtes ou bien observer l'utilité de ses index. Exemple : > db.films.find({"actors":"Bruce Willis"}).explain() Recherche de documents : Utilisation d’un filtre simple : Pour rechercher un document, nous avons besoin de placer une condition dans la commande find. Cette condition est décrite dans un document JSON. Si on veut par exemple rechercher les films de l’année 2012, il suffit d’écrire la ligne suivante : > db.films.find({"year":2012}) Pour améliorer l’affichage, on peut utiliser la commande pretty. > db.films.find({"year":2012}).pretty() C’est mieux mais ce n’est pas encore parfait car le nombre de documents retournés est important et chaque document est très riche. Projection : La projection permet de sélectionner les informations à renvoyer. Si, par exemple, nous nous intéressons uniquement au titre du film, à son année de sortie et aux noms des acteurs, je vais limiter les informations retournées en précisant les champs souhaités dans un document JSON (toujours ce fameux JSON). Et, également passer ce document comme deuxième argument de ma recherche find. > db.films.find({"year":2012},{"title":1,"year":1,"actors":1}).pretty() Pour conserver un champ, il suffit de le préciser dans ce document et de lui affecter la valeur 1. Vous aurez noté que la requête a renvoyé également le champ _id. C’est le fonctionnement normal de la commande find qui renvoie systématiquement la clé du document. Si l’on souhaite l’exclure, il faut le préciser dans la commande. > db.films.find({"year":2012},{"title":1,"year":1,"actors":1, _id:0}).pretty() Recherche dans un tableau : Les documents contiennent des champs simples comme l’année ou le titre du film mais aussi des tableaux pour stockés le nom des acteurs. Comment faire alors des recherches dans un tableau ? Tout simplement de la même manière que pour un champ simple : db.films.find({"actors":"Leonardo DiCaprio"}, {"title":1,"year":1,"actors":1, _id:0}).pretty() Vous pouvez combiner plusieurs filtres. > db.films.find({"actors":"Leonardo DiCaprio", "year":2002}, {"title":1,"year":1,"actors":1, _id:0}).pretty() Nous voulons filtrer les films avec Leonardo DiCaprio ou Tom Hanks. Pour cela, nous allons utiliser l’opérateur $in. > db.films.find({"actors":{$in:["Leonardo DiCaprio", "Tom Hanks"]}},{"title":1,"year":1,"actors":1, _id:0}).pretty() Pour avoir uniquement les films avec Leonardo DiCaprio et Tom Hanks, il existe l’opérateur $all. > db.films.find({"actors":{$all:["Leonardo DiCaprio", "Tom Hanks"]}},{"title":1,"year":1,"actors":1, _id:0}).pretty() Recherche avancée : Le langage d’interrogation de MongoDB est extrêmement puissant. Il permet de réaliser toutes les requêtes possibles et l’objectif de ce TP n’est pas d’en faire la liste exhaustive. Nous allons simplement terminer par quelques recherches un peu plus avancées. Les documents MongoDB peuvent contenir des documents imbriqués. Dans notre collection, nous avons le document awards. > db.films.findOne({},{title:1,year:1,awards:1,_id:0}) > db.films.find({"awards.wins":7}, {title:1,year:1,awards:1,_id:0}).pretty() Dans toutes nos recherches, nous avons utilisé des conditions d’égalité avec l’opérateur :. A cause des contraintes JSON, il n’est pas possible d’utiliser les signes habituels (>, >=, db.films.find({"awards.wins":{$gte:80}}, {title:1,year:1,awards:1,_id:0}).pretty() Trier les résultats : Quand les recherches renvoient beaucoup de documents, il est utile de les trier. On dispose pour cela de la fonction sort qui va permettre de trier les résultats sur un champ par ordre croissant ou décroissant. L’usage est très simple. Nous allons donc reprendre notre requête précédente et trier les résultats par ordre décroissant sur le nombre de prix obtenus. > db.films.find({"awards.wins":{$gte:80}}, {title:1,year:1,awards:1,_id:0}).sort({"awards.wins":- 1}).pretty() Insértion des documents dans MongoDB : On va commencer par insérer un document grâce à la fonction insertOne(). > use test ; > db.test.insertOne({"name":"zaidouni"}) Quand on regarde la collection, on peut constater que MongoDB, a bien inséré le document. Il a créé également une clé, nommée _id. > db.test.find() Si l’on refait la même insertion : > db.test.insertOne({"name":"zaidouni"}) On obtient le résultat suivant: MongoDB a inséré un deuxième document. Le système n’a pas détecté de doublon: il a généré une clé différente pour les deux enregistrements. On peut décider de prendre la main et définir nous même la clé _id. > db.test.insertOne({_id:0,"name":"zaidouni"}) Donc, si nous essayons cette fois-ci d’insérer un nom avec le même _id:0, cela va générer une erreur. > db.test.insertOne({_id:0,"name":"dounia"}) Nous pouvons également insérer un document avec une structure différente dans la même collection. > db.test.insertOne({"name":"toto","age":35}) > db.test.find() Il est possible d’insérer plusieurs documents en même temps. On va passer en argument un tableau de documents à la fonction insert(). > db.test.insert([{"name":"mohamed"},{"name": "othman", "ville": ["casablanca","rabat"]}]) > db.test.find() Supprimer des documents dans MongoDB : Pour supprimer une collection, on utilise la fonction drop(). On peut vérifier ensuite que la collection ne contient plus aucun document. > db.test.drop() > db.test.find() Si on ne souhaite pas supprimer la collection mais uniquement certains documents, on va utiliser la fonction deleteOne() ou deleteMany(). Comment pouvons-nous choisir les documents à supprimer ? Par une condition que l’on va passer comme argument de notre requête. Nous allons peupler de nouveau notre collection test. On refait les insertions : > db.test.insertOne({"name":"zaidouni"}) > db.test.insertOne({"name":"zaidouni"}) Imaginons que nous voulions sélectionner le deuxième document portant le nom « zaidouni ». Nous allons commencer par faire une requête pour sélectionner le document qui nous intéresse. Une fois la condition validée, nous pouvons remplacer la fonction find() par la fonction deleteOne(). Tapez donc : > db.test.find({"_id":ObjectId("61deca7ec07e57e0c93c0d6f")}) Puis : > db.test.deleteOne({"_id":ObjectId("61deca7ec07e57e0c93c0d6f")}) Mettre à jour des documents dans MongoDB : MongoDB met à disposition la fonction update avec différents opérateurs en fonction du type de mise à jour souhaité. La fonction update prend deux arguments obligatoires : - un document représentant la condition de recherche des documents de la collection, - un document représentant la mise à jour souhaitée. 1- Ajouter ou remplacer un champ existant avec $set : > db.test.update({name:"zaidouni"},{$set:{ville:"rabat"}}) > db.test.find() Dans cet exemple, on a simplement rajouté un champ ville dans le document de « zaidouni ». Rajoutons ces documents dans notre collection : > db.test.insert({name:"mohamed",age:40}) > db.test.insert({name:"zaidouni"}) Puis : > db.test.update({name:"zaidouni"},{$set:{ville:"casablanca"}}) > db.test.find() > db.test.insert({name:"mohamed",age:40}) Le résultat de la commande montre qu’un seul document a été mis à jour. La commande find montre que le premier document avec le nom « zaidouni» a bien été modifié mais pas le second. C’est une protection dans MongoDB pour empêcher par défaut la mise à jour sur de multiples documents. Si on souhaite modifier tous les documents, il faut rajouter une instruction multi: true dans notre fonction update. > db.test.update({name:"zaidouni"},{$set:{ville:"casablanca"}}, {multi:true}) 2- Incrémenter un champ numérique existant avec $inc : Dans certains cas, nous voulons faire une mise à jour en se basant sur la valeur actuelle du champ. $inc permet de rajouter une valeur à une donnée numérique. Cette valeur peut être positive ou négative. Si nous souhaitons par exemple incrémenter l’âge de « mohamed », nous pouvons exécuter la commande suivante : > db.test.update({name:"mohamed"},{$inc:{age:1} }) 3- Mettre à jour un tableau avec $push ou $pull : Si nous utilisons $set sur un tableau, nous allons remplacer le tableau existant par un nouveau élément. Comment mettre à jour le tableau sans écraser les données existantes ? L’opérateur $push permet de rajouter un nouvel élément à un tableau. > db.test.insert({"name": "othman", "ville": ["casablanca","rabat"]}) > db.test.update({"name": "othman"}, {$push:{ville:"tanger"}}) > db.test.find() Dans cet exemple, nous avons rajouté « tanger » dans le tableau contenant déjà « casablanca » et « rabat ». Il faut noter que si « tanger » était déjà présente, l’élément aurait été quand même inséré. Si l’on ne souhaite pas de doublon, il existe l’opérateur $addToSet qui assure cette fonction. Pour supprimer un élément, nous pouvons utiliser $pull. Ainsi, si nous souhaitons supprimer la ville de « rabat», il faudra lancer la commande suivante : > db.test.update({"name": "othman"}, {$pull:{ville:"rabat"}}) 3) Implémentation d’une application avec Node.js et MongoDB et réalisation des opérations CRUD Opérations CRUD : Les opérations CRUD signifie : Create, Read, Update et Delete. Ceux sont les opérations de bases qu'une application web simple doit réaliser. Les étapes d’installation de Node.js : Téléchargez nodeJs depuis le lien de son site officiel : https://nodejs.org/dist/v20.10.0/node-v20.10.0-linux-x64.tar.xz Tapez les commandes suivantes pour installer NodeJs : $ sudo mkdir /usr/local/lib/nodejs $ cd /home/zaidouni/Téléchargements/ $ sudo tar -xJvf node-v20.10.0-linux-x64.tar.xz -C /usr/local/lib/nodejs $ vim /etc/profile Si vim n’est installé, vous pouvez l’installer avec $ sudo apt install vim Ajoutez à la fin de ce fichier /etc/profile la ligne suivante : export PATH=$PATH:/usr/local/lib/nodejs/node-v20.10.0-linux-x64/bin sudo mkdir /usr/local/lib/nodejs Redemarez la machine avec la commande « reboot » ou bien taper : $ source /etc/profile Vérifiez l’installation de nodeJs, vous devez avoir la version récente v20.10.0 qui est installé: Installation de la commande npm : 1- Installez la commande npm : zaidouni@zaidouni:~$ sudo apt install npm 2- Crééz un répertoire appelé « productsapp » dans le répertoire : /home/user/Documents (par exemple) : $ cd /home/zaidouni/Documents/ $ mkdir productsapp 3- Dans ce répertoire nouvellement créé, exécutez la commande suivante : zaidouni@zaidouni:~/Documents$ cd productsapp/ zaidouni@zaidouni:~/Documents/productsapp$ npm init Les commandes ci-dessus entraînent la création d'un fichier package.json. Le fichier package.json est utilisé pour gérer les packages npm installés localement. Il comprend également les métadonnées sur le projet telles que le nom et le numéro de version. Installation des packages nécessaires: Nous allons installer les packages que nous utiliserons pour notre API qui sont : 1- ExpressJS : c'est une application Web Node.JS flexible qui a de nombreux fonctionnalités pour les applications Web et mobiles. 2- mongoose : c’est la librairie d’Object Data Modeling (ODM) pour MongoDB and Node.js. 3- body-parser : package pouvant être utilisé pour gérer les requêtes JSON. Nous pouvons installer les packages mentionnés ci-dessus en tapant ce qui suit. Assurez-vous simplement que vous êtes dans le répertoire de projet avant d'exécuter la commande ci-dessous. zaidouni@zaidouni:~/Documents$ cd productsapp/ zaidouni@zaidouni:~/Documents/productsapp$ npm install --save express body-parser mongoose Initialisation du serveur : Créez un nouveau fichier « app.js » directement dans le répertoire de l'application « productsapp » : zaidouni@zaidouni:~/Documents/productsapp$ vim app.js Ouvrez le nouveau fichier nommé app.js et ajoutez toutes les dépendances précédemment installées (ExpressJS et body-parser) en insérant le contenu suivant dans app.js : // app.js const express = require('express'); const bodyParser = require('body-parser'); // initialize our express app const app = express(); La prochaine étape serait de dédier un numéro de port et de dire à notre application express d'écouter ce port. Pour cela, ajouter le contenu suivant à la fin du fichier app.js : let port = 1234; app.listen(port, () => { console.log('Server is up and running on port number ' + port); }); Maintenant, nous devrions pouvoir tester notre serveur en utilisant la commande suivante dans le terminal : zaidouni@zaidouni:~/Documents/productsapp$ node app.js Maintenant, nous avons un serveur opérationnel. Cependant, ce serveur ne fait rien! Nous allons par la suite rendre notre application plus complexe. Organisation de l’application : Nous travaillerons avec un modèle de conception appelé MVC. C'est une bonne façon de séparer les parties de notre application et de les regrouper en fonction de leur fonctionnalité et de leur rôle. M signifie modèles (Models), cela inclura tous les code pour nos modèles de base de données (qui dans ce cas seront des produits). Ensuite le V qui représente les vues (views) et layout. Nous ne couvrirons pas les vues dans ce TP puisque nous concevons une API. La partie restante est le C, qui signifie contrôleurs (controllers), qui est la logique de comment l'application gère les demandes entrantes et les réponses sortantes. Il y a aussi autre chose, appelée Routes, elles indiquent au client (navigateur / application mobile) d'aller vers quel contrôleur une fois qu'une URL / un chemin spécifique est demandé. Dans le répertoire productsapp, nous allons créer les quatre sous-répertoires suivants : 1- controllers 2- models 3- routes 4- views Pour cela, tapez les commandes suivantes : zaidouni@zaidouni:~/Documents/productsapp$ mkdir controllers zaidouni@zaidouni:~/Documents/productsapp$ mkdir models zaidouni@zaidouni:~/Documents/productsapp$ mkdir routes zaidouni@zaidouni:~/Documents/productsapp$ mkdir views Nous avons maintenant un serveur qui est prêt à gérer nos demandes et certains répertoires qui contiendraient le code. Models : Nous allons commencer par définir notre modèle. Créez un nouveau fichier dans le répertoire « models » et appelons-le « product.model.js » : zaidouni@zaidouni:~/Documents/productsapp$ cd models/ zaidouni@zaidouni:~/Documents/productsapp/models$ vim product.model.js const mongoose = require('mongoose'); const Schema = mongoose.Schema; let ProductSchema = new Schema({ name: {type: String, required: true, max: 100}, price: {type: Number, required: true}, }); // Export the model module.exports = mongoose.model('Product', ProductSchema); Dans ce code, nous avons commencé par les exigences de mongoose, puis nous avons défini le schéma de notre modèle. La dernière chose est d'exporter le modèle pour qu'il puisse être utilisé par d'autres fichiers de notre projet. Maintenant, nous avons terminé avec la partie Models. Routes : Dans le répertoire routes, créez un fichier « product.route.js ». Il s'agit du fichier qui contiendra les routes des produits. zaidouni@zaidouni:~/Documents/productsapp/models$ cd.. zaidouni@zaidouni:~/Documents/productsapp$ cd routes/ zaidouni@zaidouni:~/Documents/productsapp/routes$ vim product.route.js Copiez le contenu suivant dans product.route.js : const express = require('express'); const router = express.Router(); // Require the controllers WHICH WE DID NOT CREATE YET!! const product_controller = require('../controllers/product.controller'); // a simple test url to check that all of our files are communicating correctly. router.get('/test', product_controller.test); module.exports = router; Controllers : L'étape suivante consiste à implémenter les contrôleurs que nous avons référencés dans les routes. Nous allons donc créer un nouveau fichier js nommé product.controller.js qui sera l'espace réservé pour nos contrôleurs qui sera placé dans le répertoire controllers. zaidouni@zaidouni:~/Documents/productsapp/routes$ cd.. zaidouni@zaidouni:~/Documents/productsapp$ cd controllers/ zaidouni@zaidouni:~/Documents/productsapp/controllers$ vim product.controller.js const Product = require('../models/product.model'); //Simple version, without validation or sanitation exports.test = function (req, res) { res.send('Greetings from the Test controller!'); }; La dernière étape avant d'essayer notre première route consiste à ajouter les lignes en gras relatif à l’ajout de la classe routes à app.js : zaidouni@zaidouni:~/Documents/productsapp$ vim app.js // app.js const express = require('express'); const bodyParser = require('body-parser'); const product = require('./routes/product.route'); // Imports routes for the products const app = express(); app.use('/products', product); const port = 1234; app.listen(port, () => { console.log('Server is up and running on port number ' + port); }); Tapez la commande suivante : zaidouni@zaidouni:~/Documents/productsapp$ node app.js Dirigez-vous maintenant vers votre navigateur et essayez le lien suivant : http://localhost:1234/products/test Postman : Postman est un client HTTP très puissant utilisé pour les tests, la documentation et le développement d'API. Nous utiliserons Postman ici pour tester nos endpoints que nous allons implémenter dans ce TP. Mais tout d’abord, nous allons installer et tester Postman. 1- Installation de Postman : Ouvrez un nouveau terminal et tapez : zaidouni@zaidouni:~/Documents/productsapp$ $ sudo snap install postman Après l’installation, taper « postman » pour pouvoir l’utiliser : $ postman Vous pouvez faire le « SignIn » avec votre compte google « Sign In with google ». Cliquez sur « Workspaces » puis « Myworkspace », ensuite créez une nouvelle collection avec « New collection » puis « Blank collection » et nommez cette collection (par exemple : TP- MongoDB) et après cliquer sur « Add Request » qui est en bleu. Ensuite, choisissez « GET » comme request et coller l’url suivant : « localhost:1234/products/test » puis cliquez sur « SEND ». Assurez-vous que votre serveur fonctionne toujours sur le numéro de port 1234. Vous devriez pouvoir voir ‘Greetings from Test controller ". Connection de l’application à la base de données MongoDB : Connection mongoose: Nous devons informer notre application qu'elle doit communiquer avec la base de données que nous avons précédemment créée dans la première partie de ce TP. Pour cela nous allons utiliser le package déjà installé de « mongoose ». Il suffit de nous diriger vers le fichier app.js et d'y coller le code suivant avant la ligne : app.use('/products', product); …. // Set up mongoose connection var mongoose = require('mongoose'); var dev_db_url = 'mongodb://127.0.0.1/tp_database'; var mongoDB = process.env.MONGODB_URI || dev_db_url; mongoose.connect(mongoDB, { useNewUrlParser: true }); mongoose.Promise = global.Promise; var db = mongoose.connection; db.on('error', console.error.bind(console, 'MongoDB connection error:')); Body Parser : La dernière chose dont nous avons besoin pour notre configuration est d'utiliser le « bodyParser ». Body Parser est un package npm utilisé pour analyser les request bodies dans un middleware. Dans le fichier app.js, ajoutez les deux lignes suivantes juste avant la ligne : app.use('/products', product); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: false})); Voici à quoi ressemble notre fichier app.js complet : // app.js const express = require('express'); const bodyParser = require('body-parser'); const product = require('./routes/product.route'); // Imports routes for the products const app = express(); // Set up mongoose connection var mongoose = require('mongoose'); var dev_db_url = 'mongodb://127.0.0.1/tp_database'; var mongoDB = process.env.MONGODB_URI || dev_db_url; mongoose.connect(mongoDB, { useNewUrlParser: true }); mongoose.Promise = global.Promise; var db = mongoose.connection; db.on('error', console.error.bind(console, 'MongoDB connection error:')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: false})); app.use('/products', product); const port = 1234; app.listen(port, () => { console.log('Server is up and running on port number ' + port); }); Tapez la commande suivante : zaidouni@zaidouni:~/Documents/productsapp$ node app.js Si vous obtenez une erreur, vérifiez la version de nodeJS qui est installé avec la commande : $ node -v Si la version de node est une version ancienne, il faut la désinstaller afin de restaurer la version récente nécessaire qui est : v20.10.0, pour cela tapez : sudo apt remove nodejs sudo apt-get autoremove Vérifiez maintenant avec node -v et relancez : $ node app.js Implémentation des Endpoints : CREATE : La première tâche de nos opérations CRUD est de créer un nouveau produit. Commençons par définir d'abord notre route. Dirigez-vous vers products.route.js et commencez à concevoir le chemin attendu que le navigateur atteindrait et le contrôleur qui serait responsable de la gestion de cette demande. Ajouter cette ligne dans products.route.js, juste avant la ligne : module.exports = router; // routes/products.route.js... router.post('/create', product_controller.product_create); Écrivons maintenant le contrôleur product_create dans notre fichier « product.controller.js ». Ajoutez les lignes suivantes à la fin du fichier « product.controller.js ». // controllers/products.js … exports.product_create = function (req, res, next) { let product = new Product( { name: req.body.name, price: req.body.price } ); product.save().then(result => { res.send('Product Created successfully') }).catch(function (err) { console.log(err); }); } La fonction consiste simplement à créer un nouveau produit à l'aide des données provenant d'une demande POST et à l'enregistrer dans notre base de données. La dernière étape serait de valider que nous pouvons facilement créer un nouveau produit. Tapez la commande pour prendre en compte les modifications : zaidouni@zaidouni:~/Documents/productsapp$ node app.js Ouvrons Postman, en tapant la commande : $postman Envoyons ensuite une demande « POST » à l'URL suivante:« localhost:1234/products/create » et choisissez l’onglet « Body » et assurez-vous également que vous choisissez : x-www-form-urlencoded Spécifiez les données POST, par exemple : name: apple price: 15 Nous pouvons voir que la réponse est «Product Created successfully ». Cela signifie que le routeur et le contrôleur fonctionnent correctement. Pour vérifier à nouveau qu'un produit «apple» a été créé, vérifions la base de données. Pour cela, connectez-vous au terminal de Mongo et vérifier qu’une table nommé : « tp_database » et une collection « products » sont bien créés. Dans un nouveau terminal, tapez : $mongo Puis : >show dbs > use tp_database > db.products.find() Read : La deuxième tâche de notre application CRUD consiste à lire un produit existant. Pour configurer la route : Ajouter cette ligne dans products.route.js, juste avant la ligne : module.exports = router; : // routes/products.route.js... router.get('/:id', product_controller.product_details); Écrivons maintenant le contrôleur product_details dans notre fichier contrôleur. Ajoutez les lignes suivantes à la fin du fichier « product.controller.js » : // controllers/products.controller.js … exports.product_details = function (req, res, next) { Product.findById(req.params.id).then(product => { res.send(product); }).catch(function (err) { console.log(err); }); }; La fonction consiste simplement à lire un produit existant à partir de l'ID de produit envoyé dans la demande. Maintenant, il faut relancer la commande pour prendre en compte les modifications : zaidouni@zaidouni:~/Documents/productsapp$ node app.js Ouvrez Postman et essayez notre nouveau Endpoint. Choisissez « GET » et appelez l'URL suivant : « localhost:1234/products/PRODUCT_ID » PRODUCT_ID est l'ID de l'objet que nous avons créé dans le Endpoint précédent. Vous devriez l'obtenir de votre base de données et ce sera certainement différent du mien qui est : « 6750a6d9ed1ff38bfc8e1b20 ». Nous avons obtenu une réponse contenant toutes les informations de ce produit spécifique. Vous pouvez voir qu'il s'appelle « apple » et que son « price » est 15. Update : La troisième tâche de notre application CRUD est de mettre à jour un produit existant. Pour configurer la route : Ajouter cette ligne dans products.route.js, juste avant la ligne : module.exports = router; : // routes/products.route.js... router.put('/:id/update', product_controller.product_update); Écrivons maintenant le contrôleur product_update dans notre fichier contrôleur. Ajoutez les lignes suivantes à la fin du fichier « product.controller.js » : // controllers/products.controller.js … exports.product_update = function (req, res,next) { Product.findByIdAndUpdate(req.params.id, {$set:req.body}).then(product => { res.send('Product udpated.'); }).catch(function (err) { console.log(err); }); }; La fonction détecte simplement un produit existant en utilisant son identifiant envoyé dans la demande. Maintenant, il faut relancer la commande pour prendre en compte les modifications : zaidouni@zaidouni:~/Documents/productsapp$ node app.js Ouvrez Postman et essayez notre nouveau Endpoint. Choisissez « PUT » et appelez l'URL suivant : « localhost:1234/products/PRODUCT_ID/update » PRODUCT_ID est l'ID de l'objet que nous avons créé dans le point de terminaison précédent. Vous devriez l'obtenir de votre base de données et ce sera certainement différent du mien. Pour tester ces modification, connectez-vous au terminal de Mongo et vérifier que la collection products a été bien modifiée. Pour cela taper : $mongo Puis : > use tp_database >db.products.find() Delete : La dernière tâche de notre application CRUD est de supprimer un produit existant. Pour configurer la route : Ajouter cette ligne dans products.route.js, juste avant la ligne : module.exports = router; : // routes/products.route.js... router.delete('/:id/delete', product_controller.product_delete); Écrivons maintenant le contrôleur product_update dans notre fichier contrôleur. Ajoutez les lignes suivantes à la fin du fichier « product.controller.js » : // controllers/products.controller.js … exports.product_delete = function (req, res, next) { Product.deleteOne({_id:req.params.id}).then(product => { res.send('Deleted successfully!'); }).catch(function (err) { console.log(err); }); }; La fonction supprime simplement un produit existant. Ouvrez Postman et essayez notre nouveau Endpoint. Choisissez « DELETE » et appelez l'URL suivant : «localhost:1234/products/PRODUCT_ID/delete» PRODUCT_ID est l'ID de l'objet que nous avons créé dans le point de terminaison précédent. Vous devriez l'obtenir de votre base de données et ce sera certainement différent du mien. Pour tester ces modification, connectez-vous au terminal de Mongo et vérifiez que la collection products a été bien supprimée. Pour cela taper : $mongo Puis : > use tp_database > db.products.find() Rapport ( à faire par binôme) : Rédigez un rapport détaillé contenant les captures d’écran et les explications des différentes manipulations effectuées dans ce TP2. Bon courage