NodeJS + Express partie 6 : Base de données MongoDB
Eric Le Codeur
Posted on November 5, 2021
Voici une série d'articles qui vous permettra créer des applications backend avec NodeJS + Express.
Cette série est la suite de ma série sur les bases de NodeJS. Si vous n'avez pas les connaissances de bases en NodeJS lisez cette série d'abord : Introduction à NodeJS
Node.js est aujourd'hui un incontournable, il est donc essentiel pour un développeur de le maitriser.
Je vais donc publier un nouvel article environ au deux jours et petit à petit vous apprendrez tout ce qu'il y a à savoir sur Node.js + Espress
Pour ne rien manquer suivez moi sur twitter : https://twitter.com/EricLeCodeur
Base de données MongoDB
Dans cette section nous allons apprendre comment manipuler une base de données MongoDB à partir de notre API.
Vous savez sans doute qu'il existe plusieurs type de base de données comme les base de données SQL et les base de donnée NoSQL.
Le but de cette article n'est pas d'expliquer en détail qu'est-ce qu'une base de données et comment elle fonctionne à l'interne. Donc un minimum de connaissance en base de données est requis.
Aujourd'hui, nous allons utiliser MongoDB qui est une base de données NoSQL
Les base de données NoSQL contiennent des collections qui eux contiennent des documents. Par exemple une base pourrait avoir la collection User et plusieurs documents qui contiendrait chacun les informations d'un user comme par exemple : no, nom, prénom, etc.
Si vous avez de l'expérience avec des bases de données SQL, on pourrait simplifier le tout en disant que les collections sont les tables et les documents sont les lignes et colonnes de la tables.
Installation MongoDB
MongoDB peut être installé sur votre machine local ou être utilisé en version cloud database.
Dans ce tutoriel nous allons créer une base de donnée MongoDB à partir de leur cloud. (https://www.mongodb.com/atlas)
Le service est gratuit et ne nécessite pas de carte de crédit.
Pour avoir accès au cloud MongoDB et ensuite pouvoir créer votre propre base de données, rendez-vous au https://www.mongodb.com/atlas et cliqué sur le bouton "Try Free".
Choisir le service Atlas, remplir le questionnaire et cliquer "Get started free"
Une fois votre compte créé, rendez-vous sur le panneau de configuration, vous devriez voir quelque chose comme cela.
Cliquez sur "Build a Database", ensuite choisir l'option "Free Shared" et cliquer sur "Create". Ensuite, conserver les options par défaut sauf la dernière option qui est "Cluster Name" et changer le nom pour "NodeExpress". Enfin cliquer sur "Create Cluster"
Créer une base de données
Votre compte MongoDB est créer et activé nous allons maintenant créer notre base de donnée et notre première collection
Votre cluster étant maintenant créer, vous devriez voir quelque chose comme cela
Pour créer une base de données et une collection. Cliquer sur "Browse Collection", ensuite sur "Add My Own Data". Enfin saisir le nom de la base de données et le nom de la collection et cliquer sur "Create"
Prêt à coder
Pour résumer, nous avons créé un compte cloud MongoDB, créer un free Cluster et créer notre première base de donnée "Demo" et enfin notre première collection "Products"
Maintenant nous sommes prêt pour coder notre API et manipuler notre base de données
Création du projet NodeJS
Nous allons maintenant créer notre projet NodeJS, je vais donner ici le code de départ (qui provient des articles précédant).
Créer un dossier
$ mkdir demo-express-mongo
$ cd demo-express-mongo
Ensuite, installation du package ExpressJS et nodemon
$ npm install express
$ npm nodemon
À noter que comme spécifié dans la section sur NodeJS, le package nodemon permet de recharger le serveur à chaque modification de notre code.
Afin de ne pas répéter les concepts que nous avons couvert dans les articles précédent, nous allons commencer avec le même code que nous avions à la fin du dernier article
Créer un dossier controllers et créer un fichier products.js avec le code suivant
const products = require('../data.js')
const getProducts = ((req, res) => {
res.json(products)
})
const getProduct = ((req, res) => {
const id = Number(req.params.productID)
const product = products.find(product => product.id === id)
if (!product) {
return res.status(404).send('Product not found')
}
res.json(product)
})
const createProduct = ((req, res) => {
const newProduct = {
id: products.length + 1,
name: req.body.name,
price: req.body.price
}
products.push(newProduct)
res.status(201).json(newProduct)
})
const updateProduct = ((req, res) => {
const id = Number(req.params.productID)
const index = products.findIndex(product => product.id === id)
const updatedProduct = {
id: products[index].id,
name: req.body.name,
price: req.body.price
}
products[index] = updatedProduct
res.status(200).json('Product updated')
})
const deleteProduct = ((req, res) => {
const id = Number(req.params.productID)
const index = products.findIndex(product => product.id === id)
products.splice(index,1)
res.status(200).json('Product deleted')
})
module.exports = {
getProducts,
getProduct,
createProduct,
updateProduct,
deleteProduct
}
Ensuite, créer un dossier "routes" et créer le fichier products.js
const express = require('express')
const router = express.Router()
const {
getProducts,
getProduct,
createProduct,
updateProduct,
deleteProduct
} = require('../controllers/products.js')
router.get('/', getProducts)
router.get('/:productID', getProduct)
router.post('/', createProduct)
router.put('/:productID', updateProduct)
router.delete('/:productID', deleteProduct)
module.exports = router
Enfin, créer un fichier app.js avec le code suivant
const express = require('express')
const app = express()
const products_routes = require('./routes/products.js')
app.listen(5000, () => {
console.log('server is listening on port 5000')
})
app.use(express.json())
app.use('/api/products', products_routes)
Jusqu'ici rien de nouveau, nous somme prêt pour continuer ce code en ajoutant notre base de données MongoDB
fichier .env
Pour connecter à notre base de donnée MongoDB nous avons besoins du URL de connection. MongoDB va nous fournir ce URL. Le truc c'est que pour des raisons de sécurité évidente, nous ne pouvons pas utiliser ce URL de connection directement dans notre code.
Le URL de connection dois être placé dans un fichier qui sera hors d'atteinte des utilisateurs lors du déploiement.
Pour ce faire nous allons donc créer un fichier qui contiendra notre URL de connection. Par convention ce fichier de nomme ".env" (dot env)
Vous pouvez créer ce fichier à la racine du projet et inclure le URL de connection MongoDB
// .env
MONGO_URI = 'mongodb+srv://<username>:<password>@nodeexpress.my1j7.mongodb.net/myFirstDatabase?retryWrites=true&w=majority'
Pour obtenir votre URL de connection de MongoDB. Connectez-vous à votre compte MongoDB cloud et à partir du menu "Databases" cliquer sur "Connect", ensuite choisir l'option "Connect you application"
MongoDB va vous afficher votre connection string, copiez là et collez là dans votre fichier .env
Dans la connection string, remplacer et avec votre nom d'utilisateur et mot de passe utilisateur cloud MongoDB et également remplacer "myFirstDatabase" avec le nom de votre base de données (soit "demo")
Communiquer avec MongoDB à partir de NodeJS
Il existe plusieurs façon de communiquer avec votre base de donnée MongoDB. Pour ce projet j'ai décidé d'utiliser le package NodeJS nommé "mongoose"
Ce packages permet facilement le lier MongoDB et votre API.
ODM
mongoose est un ODM (Object Document Mapping) ce qui signifie que mongoose permet de créer un object (appelé modèle) pour représenter et manipuler chacune de nos collections.
Cet object (model) contiendra plusieurs fonctions pré-définit qui permettront de manipuler facilement la collection associé à cet objet.
Une fois le modèle créé, pas besoin de manipuler la base de donnée, simplement utiliser les méthodes de l'object modèle et lui se chargera de communiquer à la base de donnée. Du coup, ce pattern permet d'augmenter de façon significative la facilité de manipuler la base de donnée.
Voici un exemple rapide afin visualiser le concept
const products = await Product.find({})
Dans ce code, l'objet/model "Product" utilise la méthode "find" afin de lire tous les documents de la collection. Les documents récupérer sont envoyé dans la variables "products".
Creation d'un modèle mongoose
Nous allons maintenant créer un object/model "Product"
La première étape est d'installer le package mongoose
npm install mongoose
npm install dotenv
Tant qu'a y être nous allons également installer le package dotenv. Ce package permet de lire le fichier de config ".env" que nous avons créer plus tôt et de charger ses variables dans le processus en cours.
Une fois le package utilisé, nous pouvons créer notre premier modèle mongoose.
Créer un dossier "models" et créer le fichier Product.js
const mongoose = require('mongoose')
const ProductSchema = new mongoose.Schema({
name:String,
price: Float,
})
const Product = mongoose.model('Product', ProductSchema)
module.exports = Product
Les modèles mongoose sont créer à partir des schémas.
Le schéma permet de définir la structure d'un document. (Un peu comme les colonnes d'une table dans une base de données SQL).
Dans le dernier exemple nous définissons le schema Product qui sera la structure des documents de la collection Products
L'avant dernière ligne permet de créer le model Product à partir du schema
const Product = mongoose.model('Product', ProductSchema)
Connection à la base de données
Maintenant que nous avons un modèle mongoose pour travailler, il faut maintenant établir la connection entre mongoose et notre base de donnée MongoDB.
Modifier le fichier app.js afin d'inclure le code de connection à la base de donnée.
const express = require('express')
const mongoose = require('mongoose')
const app = express()
const products = require('./data.js')
const products_routes = require('./routes/products.js')
require('dotenv').config()
mongoose.connect(process.env.MONGO_URI)
.then((result) => app.listen(5000))
.catch((err) => console.log(Error))
app.use(express.json())
app.use('/api/products', products_routes)
Reprenons le code avec quelques explications:
Envoi le contenu du fichier .env dans l'object process.env
require('dotenv').config()
Utilise le MONGO_URL pour créer un connection avec votre base de donnée
mongoose.connect(process.env.MONGO_URI)
Si la connection est réussit alors lancer le serveur NodeJS sinon afficher l'erreur.
mongoose.connect(process.env.MONGO_URI)
.then((result) => app.listen(5000))
.catch((err) => console.log(Error))
CRUD API
Maintenant que nous avons notre connection à MongoDB, nous pouvons modifier notre fichier "products" controller (/controllers/products.js) et y ajouter les méthodes du model Produit.
En faite le fonctionnement de ces méthodes est tellement simple et explicite que nous n'avon pas besoin de les expliquer.
const Product = require('../models/Product.js')
const getProducts = ((req, res) => {
Product.find({})
.then(result => res.status(200).json({ result }))
.catch(error => res.status(500).json({msg: error}))
})
const getProduct = ((req, res) => {
Product.findOne({ _id: req.params.productID })
.then(result => res.status(200).json({ result }))
.catch(() => res.status(404).json({msg: 'Product not found'}))
})
const createProduct = ((req, res) => {
Product.create(req.body)
.then(result => res.status(200).json({ result }))
.catch((error) => res.status(500).json({msg: error }))
})
const updateProduct = ((req, res) => {
Product.findOneAndUpdate({ _id: req.params.productID }, req.body, { new: true, runValidators: true })
.then(result => res.status(200).json({ result }))
.catch((error) => res.status(404).json({msg: 'Product not found' }))
})
const deleteProduct = ((req, res) => {
Product.findOneAndDelete({ _id: req.params.productID })
.then(result => res.status(200).json({ result }))
.catch((error) => res.status(404).json({msg: 'Product not found' }))
})
module.exports = {
getProducts,
getProduct,
createProduct,
updateProduct,
deleteProduct
}
Toutefois, si vous désirez connaitre en détail le fonctionnement de ces méthodes et les autres méthodes disponibles, consultez la documentation de mongoose ici : https://mongoosejs.com/docs/models.html
Tester votre API
Vous pouvez maintenant lancer le serveur Node.JS et tester l'API
$ npx nodemon app.js
Le serveur sera lancé sur le port 5000 accessible au localhost:5000
À l'aide d'un logiciel comme Postman, vous pouvez maintenant tester votre API avec les requêtes suivantes :
GET localhost:5000/api/products
GET localhost:5000/api/product/<id>
POST localhost:5000/api/products
PATCH localhost:5000/api/products/<id>
DELETE localhost:5000/api/products/<id>
À noter que pour les actions POST et PATH, vous devez les envoyer avec du contenu dans la section body de votre requête. Voici un exemple de contenu en JSON :
{
"name": "iPhone12",
"price": 899
}
Conclusion
C'est tout pour aujourd'hui, suivez moi sur twitter : https://twitter.com/EricLeCodeur afin d'être avisé de la parution du prochain article (d'ici deux jours).
Posted on November 5, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.