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