NodeJS + Express partie 6 : Base de données MongoDB
Tags: javascript, node, express, beginners
Published: 2021-11-05 11:49:54

---
title: NodeJS + Express partie 6 : Base de données MongoDB
description: 
published: true
tags: javascript, nodejs, express, beginner
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mpa8fz4kcbvpze7lp8e2.png
series: expressJS
---

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](https://dev.to/ericlecodeur/creer-un-backend-en-javascript-introduction-a-node-js-3014)

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

<hr>
## 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](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](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.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dohevr4qc82egrnr7cfy.png)

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
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ehpoghbwp1173btvwpm4.png)

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"

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7o8wrzvi1dkrurg1ujxr.png)

### 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

```bash
$ mkdir demo-express-mongo
$ cd demo-express-mongo
```

Ensuite, installation du package ExpressJS et nodemon

```jsx
$ 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

```jsx
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

```jsx
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

```jsx
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

```jsx
// .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"
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tgccpueo7fi8hmayf336.png)


MongoDB va vous afficher votre connection string, copiez là et collez là dans votre fichier .env 

Dans la connection string, remplacer  <username> et <password> 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

```jsx
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

```jsx
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

```jsx
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

```jsx
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.

```jsx
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

```jsx
require('dotenv').config()
```

Utilise le MONGO_URL pour créer un connection avec votre base de donnée 

```jsx
mongoose.connect(process.env.MONGO_URI)
```

Si la connection est réussit alors lancer le serveur NodeJS sinon afficher l'erreur.

```jsx
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.

```jsx
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](https://mongoosejs.com/docs/models.html)

### Tester votre API

Vous pouvez maintenant lancer le serveur Node.JS et tester l'API

```jsx
$ 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 :

```json
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 :

```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).