Créer un serveur Node.js avec Express.js
Tags: javascript, french, tutorial, mern
Published: 2022-01-24 16:17:08

Dans le développement web une stack est une combinaison de technologie, la MERN stack est une des combinaison les plus populaire en 2022. Cette stack se compose de : 
* Mongo DB
* Express.js
* React.js
* Node.js

Nous allons voir comment aborder cette stack en commençant par la configuration d'un serveur Node.js avec le framework Express.js relié à une base de données Mongo DB.

## Express
Express est un framework Node.js minimaliste et flexible, il est du fait facile d'utilisation et laisse une certaine liberté au développeur. Il permet notamment de créer des API à l'aide d'une floppée de méthodes HTTP.

## Mongo DB
Mongo DB est un gestionnaire de base de données NoSQL. [Pour plus de détail.](https://www.mongodb.com/cloud/atlas/lp/try2?utm_source=bing&utm_campaign=mdb_bs_emea_france_search_core_brand_atlas_desktop&utm_term=mongodb&utm_medium=cpc_paid_search&utm_ad=e&utm_ad_campaign_id=415204542&adgroup=1222657400083870&msclkid=5d8de6dc3bd51a7af8e68732f8b29e27) Vous pouvez créer un compte si vous n'en avez pas. Une fois le compte créé, vous allez pouvoir créer votre premier cluster en sélectionner l'option FREE, then choose the options you want and clic Create cluster.
![Mongo DB cluser selection](https://i.postimg.cc/rwVzMDw5/2022-01-24-16-22-54-Choose-a-Path-Cloud-Mongo-DB-Cloud-et-17-pages-de-plus-Personnel-Microsoft.png)
Après cela vous allez devoir créer les identifiants pour accéder à votre base de données. Notez les bien.
![Mongo DB account config](https://i.postimg.cc/s2PnS0Rk/2022-01-24-16-31-44-Security-Quickstart-Mongo-DB-et-19-pages-de-plus-Personnel-Microsoft-Edge.png)
Enfin définnisez les adresses IP pouvant accéder au projet:
![Mongo DB Atlas access](https://i.postimg.cc/sDZ470YT/2022-01-24-16-33-04-Security-Quickstart-Mongo-DB-et-20-pages-de-plus-Personnel-Microsoft-Edge.png) 


## Phase de développement
[1.  Initialisation du projet](#initialisation-du-projet)<br>
[2.  Instalation des packages](#installation-des-package)<br>
[3.  Configuration de l'environnement](#configuration-de-environnement)<br>
[4.  Configuration de la base de données](#configuration-de-bdd)<br>
[5.  Initialisation du server](#configuration-de-server)<br>
[6.  Configuration des routeurs](#configuration-de-routes)

## Initialisation du projet <a id="initialisation-du-projet"></a>
La première étape pour créer un serveur Express.js est d'initialiser un projet npm. [Pour en savoir plus sur npm.](https://www.npmjs.com/) Pour cela il faut créer un dossier server et ensuite taper la commande npm init à l'intérieur : 
```javascript
mkdir express-server-article
cd express-server-article
npm init -y

// RESULT
Wrote to C:\Users\aurel\Documents\Areatomic\Livre\articles\express-server-article\package.json:

{
  "name": "express-server-article",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
```

## Installation des packages <a id="installation-des-package"></a>
Maintenant que le projet est configurer nous devons installer les packages nécessaires à son fonctionnement. Pour réaliser un serveur express basique nous avons besoin des packages suivant:
* express : permet de construire la base du serveur
* mongoose : permet d'utiliser une base de données Mongo DB
* config : permet de configurer proprement notre projet
* dotenv : permet de configurer notre environnement
* cors : permet de définir une politique de restriction d'accès au serveur
* nodemon : permet de lancer un serveur que se relance automatiquement à la sauvegarde.
* prettier : permet de définir des règles de formatage de code

L'installation de ces packages se fait à l'aide de la commande npm install:
```npm
npm install express mongoose config dotenv cors nodemon prettier
```
Rajouter ensuite le script ```"start":"nodemon index.js``` dans le fichier package.json.
Au final le fichier ```package.json``` doit ressembler au code ci-dessous:
```JSON
{
  "name": "express-server-article",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "nodemon index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "config": "^3.3.7",
    "cors": "^2.8.5",
    "dotenv": "^14.2.0",
    "express": "^4.17.2",
    "mongoose": "^6.1.7",
    "nodemon": "^2.0.15",
    "prettier": "^2.5.1"
  }
}
```

## Configuration de l'environnement <a id="configuration-de-environnement"></a>
L'environnement est un élément essentiel au fonctionnement d'un serveur. Nous pouvons le configurer grâce à un fichier ```.env```. Nous y définissons la base de données, le port sur lequel tourne le serveur, la whitelist pour les options CORS, etc.

```
PORT=5000
DATABASE=mongodb+srv://areatomic:jaihackermongodb@aeratomic.onbwm.mongodb.net/express-server-article?retryWrites=true&w=majority
WHITELIST=['http://localhost:3000']
SERVER_URL=http://localhost:5000
```
Vous pouvez récupérer le lien connexion à la base de données en cliquant sur le bouton connect de votre cluster puis en copiant les éléments dans l'onglet "Connect your application".

## Configuration de la base de données <a id="configuration-de-bdd"></a>
Pour connecter notre base de données fraichement créée, nous allons réaliser cela dans un dossier ```config``` et dans un fichier ```index.js```.
![Arbre config](https://i.postimg.cc/KvHLq7NR/2022-01-24-16-39-16-index-js-Livre-Visual-Studio-Code.png)

Voici ce que contient le fichier ```index.js```:
```JavaScript
/**
 * Config .env
 */
 const dotenv = require('dotenv')
 const mongoose = require('mongoose')
 dotenv.config()
 
 /**
  * Config mongo
  */
 const connectDB = async () => {
     try {
         await mongoose.connect(process.env.DATABASE, {
             useNewUrlParser: true,
             useUnifiedTopology: true,
         })
         console.log('Connection to Mongo DB done')
     } catch (err) {
         console.error(err.message)
         // Exit process with failure
         process.exit(1)
     }
 }
 
 module.exports = connectDB
```

Nous créons une fonction connectDB asynchrone (qui utilise des méthode nécessistant d'attendre un retour) dans laquelle nous utilisons la méthode connect avec l'URL renseigner dans notre fichier ```.env```.

## Configuration du serveur <a id="configuration-de-server"></a>
Maintenant que nous avons configurer notre environnement et notre base de données, il ne reste plus qu'à configurer la base du serveur. Pour cela créer un fichier ```index.js``` à la racine du projet.

Première étape importer les packages :
```JavaScript
const express = require('express')
const cors = require('cors')
const dotenv = require('dotenv')
const connectDB = require('./config')
```

Seconde étape lecture des configurations:
```JavaScript
 dotenv.config()
 //Database
 connectDB()
 ```

Troisième étape lancement du serveur à proprement parler :
```javascript
const app = express()
app.listen(process.env.PORT, () => {
    console.log(`API is running on ${process.env.SERVER_URL}`)
})
```

Enfin définition des sécurités du serveur:
```JavaScript
 app.use(express.json({ extended: false }))
 // CORS
 app.use(
     cors({
         origin: (origin, callback) => {
             if (!origin) return callback(null, true)
             if (process.env.WHITELIST.indexOf(origin) === -1) {
                 let message =
                     "The CORS policy for this origin doesn't " +
                     'allow access from the particular origin.'
                 return callback(new Error(message), false)
             }
             return callback(null, true)
         },
     })
 )
```

Une fois que cela est terminé le fichier ressemble à cela:
```JavaScript
const express = require('express')
const cors = require('cors')
const dotenv = require('dotenv')
const connectDB = require('./config')

/**
 * Config serveur
 */
 dotenv.config()
 //Database
 connectDB()

 //Serveur
 const app = express()
 app.listen(process.env.PORT, () => {
     console.log(`API is running on ${process.env.SERVER_URL}`)
 })
 app.use(express.json({ extended: false }))
 // CORS
 app.use(
     cors({
         origin: (origin, callback) => {
             if (!origin) return callback(null, true)
             if (process.env.WHITELIST.indexOf(origin) === -1) {
                 let message =
                     "The CORS policy for this origin doesn't " +
                     'allow access from the particular origin.'
                 return callback(new Error(message), false)
             }
             return callback(null, true)
         },
     })
 )
```

Le projet peut être lancé avec la commande
```js
PS C:\Users\aurel\Documents\Areatomic\Livre\articles\express-server-article> npm start
// OUTPUT

> express-server-article@1.0.0 start
> nodemon index.js

[nodemon] 2.0.15
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node index.js`
API is running on http://localhost:5000
Connection to Mongo DB done
```

## Configuration des routes <a id="configuration-de-routes"></a>
Enfin pour finaliser la construction de notre serveur nous allons définir une route par défaut. Pour cela créer une dossier ```config``` avec un sous-dossier ```routes``` et un sous-dossier ```controller``` pour vos futur projets. Dans le dossier ```routes``` créer un fichier ```index.js```:
```JavaScript
//* Import des modules *//
const express = require('express')
const router = express.Router()

//* Création de la routes *//
router.get('/', (req, res) => {
    res.send('API is running.')
})

// Export
module.exports = router 
```

Une fois le fichier créer il faut l'importer et l'utiliser dans le fichier ```index.js``` à la racine du projet:
```JavaScript
/* ... Other imports */
const routes = require('./api/routes');
/**
 * Config serveur
 */
/* ... Le reste du fichier */
app.use('/', routes);
```

En vous rendant sur l'url [http://localhost:5000](http://localhost:5000) vous verez écris "API is running." Félicitations !