---
# System prepended metadata

title: Node simple API
tags: [javascript, ' nodejs']

---

---
title: Node simple API
tags: javascript, nodejs
robots: noindex, nofollow
author: Julien Noyer
---

# NodeJS : création d'une API de base

Mise en placee du code de départ du fichier `server.js` :

```js
/* 
Import
*/
    // NodeJS
    require('dotenv').config();
    const express = require('express');
    const bodyParser = require('body-parser');
    const path = require('path');
    const ejs = require('ejs');
    const cors = require('cors');
//


/* 
Config
*/
    // Declarations
    const server = express();
    const port = process.env.PORT    

    // Server class
    class ServerClass{
        init(){
            // Set CORS
            server.use(cors());

            // View engine configuration
            server.set('view engine', 'ejs');

            // Static path configuration
            server.set( 'views', __dirname + '/www' );
            server.use( express.static(path.join(__dirname, 'www')) );

            //=> Body-parser
            server.use(bodyParser.json({limit: '10mb'}));
            server.use(bodyParser.urlencoded({ extended: true }));

            // Start server
            this.launch();
        };

        launch(){
            // Start server
            server.listen(port, () => console.log({ server: `http://localhost:${port}` }))
        };
    };
//


/* 
Start
*/
    new ServerClass().init();
//
```

Création du fichier `.env` a la racine du dossier `server` :

```bash
touch .env
```

Copier coller le code suivant dans le fichier `.env` :

```bash
# Basic
PORT=2785
```

Puis lancer votre serveur depuis lee dossier `server` :

```bash
node server.js
```

A présent créer un dossier `www` dans le dossier `server` puis ajouteez-y un fichier `index.ejs`contenant le code suivant :

```htmlmixed=
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Node Simple API</title>
    </head>
    
    <body>
        <header>
            <h1>Node Simple API</h1>
        </header>
    </body>
</html>
```

Ajouter après la méthode `init()` du serveur la gestion des routes :

```js
serverRoutes(){
    /* 
    Front router
    */
        // Homepage
        server.get( '/', (req, res) => res.render('index', { title: 'NodeJS simple API' }) );
    //
}
```

Une fois la gestion des routes ajputée, appelez la méthode en premier dans la methode `launch` : 

```js
launch(){
    // Init Routers
    this.serverRoutes();

    // Start server
    server.listen(port, () => console.log({ server: `http://localhost:${port}` }))
};
```

Modifier la balise `h1` du fichier `index.ejs` : 

```html
<h1><%= title %></h1>
```

Ajouter les routes `api` dans la méthode `serverRoutes()` : 

```js
/*
API router
*/
    // CRUD : create item
    server.post( '/api/post', (req, res) => {
        // Send back data to the client
        res.json({
            msg: 'Post created!',
            data: null,
            error: null,
            status: 201
        })
    });
    
    // CRUD : read item by id
    server.get( '/api/post/:id', (req, res) => {
        // Send back data to the client
        res.json({
            msg: 'Post send!',
            data: null,
            error: null,
            status: 200
        })
    });
    
    // CRUD : read all items
    server.get( '/api/post', (req, res) => {
        // Send back data to the client
        res.json({
            msg: 'Posts send!',
            data: null,
            error: null,
            status: 200
        })
    });
    
    // CRUD : update item by id
    server.put( '/api/post/:id', (req, res) => {
        // Send back data to the client
        res.json({
            msg: 'Post send!',
            data: null,
            error: null,
            status: 201
        })
    });
    
    // CRUD : delete item by id
    server.delete( '/api/post/:id', (req, res) => {
        // Send back data to the client
        res.json({
            msg: 'Post send!',
            data: null,
            error: null,
            status: 201
        })
    });
//
```

Mettrez à jour votre fichier `package.json` avec les données suivantes : 

```json=
{
  "name": "<project-name>",
  "version": "1.0.0",
  "description": "",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "nodemon server.js",
    "launch-db": "json-server --watch ../data/db.json"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.19.0",
    "cors": "^2.8.5",
    "dotenv": "^8.2.0",
    "ejs": "^3.0.1",
    "express": "^4.17.1",
    "mongoose": "^5.7.13",
    "node-fetch": "^2.6.0",
    "path": "^0.12.7"
  }
}
```

Vous pouvez à présent lancer les commandes : 

```bash
npm start
npm run launch-db
```
Pourr réaliser des requête feetch en NodeJS, vous deevez tout d'abord importerr `NodeFetch` dans votre seerver : 

```js
const fetch = require('node-fetch');
```

Mettre à jour la fonction `CRUD : read all items` : 

```js
server.get( '/api/post', (req, res) => {
    // Start Fetch reequest
    fetch( 'http://localhost:3000/post', {
        method: 'GET'
    })
    // Get Fetch response
    .then( response => {
        // Check response
        if( response.ok ){
            // Extraire les données en JSON
            return response.json();
        }
        else{
            res.json({
                msg: 'Fetch error',
                data: null,
                error: response,
                status: 500
            })
        }
    })
    // Get json data from response
    .then( jsonData => {
        // Send back json data to client
        res.json({
            msg: 'Post data sended!',
            data: jsonData,
            error: null,
            status: 200
        })
    })
    // Get Fetch request error
    .catch( error => {
        res.json({
            msg: 'Fetch error',
            data: null,
            error: error,
            status: 500
        })
    });
})
```

Une fois cette fonction ajoutée, vous devez afficherr surr la rroute api/post les données suivantes : 

```json=
{
"msg": "Post data sended!",
    "data": [
        {
            "id": 1,
            "title": "Lorem, ipsum dolor sit amet",
            "body": "Consectetur adipisicing elit. Cum sed eum itaque, facere non nobis repellendus aliquid dolore, nulla velit tempora expedita cupiditate optio eligendi laboriosam dolorem voluptates repellat alias."
        }
    ],
    "error": null,
    "status": 200
}
```

A prrésent metter a jour la fonction `CRUD: read item by id` : 

```js
server.get( '/api/post/:id', (req, res) => {
    // Get request param id
    const paramId = req.params['id'];
    
    // Start Fetch reequest
    fetch( `http://localhost:3000/post/${paramId}`, {
        method: 'GET'
    })
    // Get Fetch response
    .then( response => {
        // Check response
        if( response.ok ){
            // Extraire les données en JSON
            return response.json();
        }
        else{
            res.json({
                msg: 'Fetch error',
                data: null,
                error: response,
                status: 500
            })
        }
    })
    // Get json data from response
    .then( jsonData => {
        // Send back json data to client
        res.json({
            msg: 'Post data sended!',
            data: jsonData,
            error: null,
            status: 200
        })
    })
    // Get Fetch request error
    .catch( error => {
        res.json({
            msg: 'Fetch error',
            data: null,
            error: error,
            status: 500
        })
    });
})
```

A préseent nous allons optimiser le  code en créant un service. Vous devez ajoiuter un dossier `services` à la racine du dossierr `server` et y ajouter un fichier `fetch.service.js` : 

```bash
mkdir services
touch services/fetch.service.js
```

Le contenu du fichier `fetch.service.js` est le suivant : 

```js
/*
Import
*/
    const fetch = require('node-fetch');
//

/*
Methods
*/
    // CRUD: create item
    const createItem = () => {
    
    };
    
    // CRUD: read all items
    const readAllItems = () => {
        // Return new Promise
        return new Promise( (resolve, reject) => {
        
            // Start Fetch request
            fetch( 'http://localhost:3000/post', {
                method: 'GET'
            })
            // Get Fetch response
            .then( response => {
                // Check response
                if( response.ok ){
                    // Extraire les données en JSON
                    return response.json();
                }
                else{
                    return reject(reponse);
                }
            })
            // Get json data from response
            .then( jsonData => {
                return resolve(jsonData);
            })
            // Get Fetch request error
            .catch( error => {
                return reject(error);
            });
        })
        
    };
    
    // CRUD: read item by id
    const readItem = () => {
    
    };
    
    // CRUD: update item by id
    const updateItem = () => {
    
    };
    
    // CRUD: delete item by id
    const deleteItem = () => {
    
    };
//

/*
Exports
*/
    module.exports = { createItem, readAllItems, reaedItem, updateItem, deleteItem }
//
```

A présent il faut importer les méthodes du fichier `fetch.service.js` dans `server.js` de la façon suivante : 

```js
const { createItem, readAllItems, reaedItem, updateItem, deleteItem } = require('./servives/fetch.service');
```

Mettez à jour la route `GET api.post` de la manière suivante : 

```js
server.get( '/api/post', (req, res) => {

    // Use the service method
    readAllItems()
    // => Get the Promise.resolve() data
    .then( data => {
        res.json({
            msg: 'Data send!',
            data: data,
            error: null,
            status: 200
        })
    })
    // => Get the Promise.reject() data
    .catch( error => {
        res.json({
            msg: 'Data not send!',
            data: null,
            error: error,
            status: 500
        })
    })

})
```

Mettre à jour la méthode `readItem` du fichier `fetch.service.js` avec le code suivant : 

```js
// CRUD: read item by id
const readItem = ( endpoint ) => {
    // Return new Promise
    return new Promise( (resolve, reject) => {
        
        // Start Fetch request
        fetch( `http://localhost:3001/${endpoint}`, {
            method: 'GET'
        })
        // Get Fetch response
        .then( response => {
            // Check response
            if( response.ok ){
                // Extraire les données en JSON
                return response.json();
            }
            else{
                return reject(reponse);
            }
        })
        // Get json data from response
        .then( jsonData => {
            return resolve(jsonData);
        })
        // Get Fetch request error
        .catch( error => {
            return reject(error);
        });
    })
};
```

Vous pouveez à présent utiliserr cette méthode epour les routes `GET api/post` et `GET api/pos/id` de la façon suivante : 

```js
// CRUD : read item by id
server.get( '/api/post/:id', (req, res) => {

    // Use the service method
    reaedItem(`post/${req.params['id']}`)
    // => Get the Promise.resolve() data
    .then( data => {
        res.json({
            msg: 'Data send!',
            data: data,
            error: null,
            status: 200
        })
    })
    // => Get the Promise.reject() data
    .catch( error => {
        res.json({
            msg: 'Data not send!',
            data: null,
            error: error,
            status: 500
        })
    })

})

// CRUD : read all items
server.get( '/api/post', (req, res) => {

    // Use the service method
    reaedItem('post')
    // => Get the Promise.resolve() data
    .then( data => {
        res.json({
            msg: 'Data send!',
            data: data,
            error: null,
            status: 200
        })
    })
    // => Get the Promise.reject() data
    .catch( error => {
        res.json({
            msg: 'Data not send!',
            data: null,
            error: error,
            status: 500
        })
    })

})
```

A présent, nous allons créer un formulaire front, placez-vous dans le dossier `www` pour créer un dossier `partials` avec à l'intérrieur un fichier `form.add.post.ejs` : 

```bash
mkdir partials
touch parrtials/form.add.post.ejs
```
Le co,ntenu du fichier `form.add.post.ejs` eest le suivant : 

```htmlmixed=
<form action="#"">
    <label for="title">Title</label>
    <input type="text" name="title" id="title" minlength="5" required>

    <label for="body">Content</label>
    <textarea name="body" id="body" minlength="5" required></textarea>

    <button type="submit">Add post</button>
</form>
```

A présent, ouvrez le fichier `index.ejs` pour ajouter le formulaire de la façon suivante : 

```htmlmixed=
<%- include('partials/form.add.post.ejs') %>
```

Nous allons a présent ajouter un script dans le fichier `form.add.post.ejs` pour capter la validation du forrmulaire et envoyer les données en fetch : 

```js
<script>

    document.addEventListener('DOMContentLoaded', () => {

        /* 
        Déclaration
        */
            let addPostForm = document.querySelector('#addPostForm');
            let title = document.querySelector('#title');
            let body = document.querySelector('#body');
        //

        /* 
        Functions
        */
            const getFormSubmit = () => {
                // Get form submission
                addPostForm.addEventListener('submit', event => {
                    // Disable submit event
                    event.preventDefault();

                    // Check values
                    if( 
                        title.value.length >= 5 &&
                        body.value.length >= 5
                    ){
                        // Send data with Fetch
                        fetch('/api/post', {
                            method: 'POST',
                            headers: { 'Content-Type': 'application/json' },
                            body: JSON.stringify({
                                title: title.value,
                                body: body.value
                            })
                        })
                        // Get Fetch response
                        .then( response => {
                            // Check response
                            return reponse.ok ? reponse.json : console.error(response)
                        })
                        // Get json data from response
                        .then( jsonData => {
                            console.log(jsonData)
                        })
                        // Get Fetch request error
                        .catch( err => {
                            console.error(err);
                        }); 
                    }
                })

            }
        //

    })
</script>
```

Il faut à présent éditer le fichier `server.js` pour être capable de récupérer les donnée provenant du formulaire. Il faut éditer la route `POST api/post` de la fçon suivante : 

```js
server.post( '/api/post', (req, res) => {
    // Get data from rrequest body
    const bodyData = req.body;

    // Send back data to the client
    res.json({
        msg: 'Post created!',
        data: bodyData,
        error: null,
        status: 201
    })
});
```

Pour pouvoir inscire un nouveeau post dans la base de données il faut éditer la fonction `createItem()` du fichier `fetch.service.js` de la façon suiuvante : 

```js
const createItem = ( endpoint, data ) => {
    // Return new Promise
    return new Promise( (resolve, reject) => {
        // Start Fetch request
        fetch( `http://localhost:3001/${endpoint}`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify(data)
        })
        // Get Fetch response
        .then( response => {
            // Check response
            if( response.ok ){
                // Extraire les données en JSON
                return response.json();
            }
            else{
                return reject(reponse);
            }
        })
        // Get json data from response
        .then( jsonData => {
            return resolve(jsonData);
        })
        // Get Fetch request error
        .catch( error => {
            return reject(error);
        });
    })
};
```

A présent ouvrez le fichier `server.js` pour mettre à jour la route `POST api/post` de la façon suivante : 

```js
server.post( '/api/post', (req, res) => {
    // Get data from rrequest body
    const bodyData = req.body;

    // Use the service method
    createItem( 'post', bodyData )
    // => Get the Promise.resolve() data
    .then( data => {
        res.json({
            msg: 'Data created!',
            data: data,
            error: null,
            status: 201
        })
    })
    // => Get the Promise.reject() data
    .catch( error => {
        res.json({
            msg: 'Data not created!',
            data: null,
            error: error,
            status: 500
        })
    })
});
```


Nous allons a présent créer une liste dans le front pour affiche les post. Placez voous dans le dossier `partials` popur créer une fihcier `list.post.ejs` contenant le code suivant : 

```htmlmixed=
<ul id="postList"></ul>

<script>
    document.addEventListener('DOMContentLoaded', () => {
    
        fetch('/api/post', {
            method: 'GET'
        })
        // Get Fetch response
        .then( response => {
            return response.ok ? response.json() : console.error(reesponse)
        })
        // Extract json data
        .then( jsonData => {
            // Make a loop on jsonData colleection
            for( let post of jsonData.data ){
                // Add on post in the list
                document.querySelector('#postList').innerHTML += `
                    <li>
                        <p>${post.title}</p>
                        <a href="post/${post.id}">Reead more...</a>
                    </li>
                `;
            }
        })
        // Get Fetch error
        .catch( err => console.error(err));
    
    })
</script>
```