Comment construire une API RESTful simple avec NodeJs, ExpressJs et MongoDb

Mis à jour le 11 juillet 2019: Cet article a été une étape majeure pour atteindre plus de 70 000 lecteurs. D'après les commentaires reçus, il a été utile pour de nombreuses personnes qui ont essayé de créer des API avec NodeJs. Pour améliorer cela, j'ai mis à jour des extraits de code dans ce tutoriel afin de corriger les bogues identifiés par la plupart des lecteurs. Merci à tous pour vos bonnes réponses, j'espère trouver le temps bientôt pour en écrire un autre bon. Allez-y et construisez des applications étonnantes pour le monde - David Inyangetoh

Les API RESTFul existent depuis quelque temps déjà. Au moment de cet article, il est pratiquement impossible pour vous d’être un développeur de logiciels sans avoir à créer et à utiliser une ou plusieurs API.

API est un acronyme pour Application Programming Interface qui est devenu une partie intégrante du développement logiciel. «C’est un ensemble de méthodes de communication clairement définies entre différents composants» - Wikipedia.

Les API RESTFul, en revanche, sont des API conformes au style architectural REST. REST fait référence à Representational State Transfer qui "est un style architectural qui définit un ensemble de contraintes et de propriétés basées sur HTTP".

L’implémentation la plus courante du service Web RESTFul est l’API JSON et c’est ce à quoi nous allons travailler dans ce tutoriel. Vous pouvez en savoir plus sur les spécifications JSONAPI, des exemples et la mise en œuvre ici. JSON est simplement une notation objet Javascript.

Dans ce tutoriel, nous construisons une API simple utilisant ExpressJs et MongoDb avec des fonctions CRUD pour les contacts.

Applications requises

  • NodeJS
  • Facteur
  • MongoDb
  • IDE

Commençons…

Démarrer le projet

Pour amorcer notre projet, nous devons vérifier que NodeJs, NPM et MongoDb sont installés sur notre machine. Pour ce faire, ouvrez votre terminal ou votre invite de commande et exécutez

noeud -v

Ceci vérifie la version de Nodejs installée. Courir

npm -v

vérifier que Node Package Manager (npm) est installé. Voir la sortie ci-dessous

Maintenant que nous avons vérifié que Node et NPM sont installés, nous pouvons continuer à configurer notre projet. Si Node n'est pas installé sur votre ordinateur, vous devez télécharger une version compatible avec votre système d'exploitation ici et l'installer avant de continuer.

Ensuite, nous devons vérifier que MongoDb est installé en exécutant

mongo --version

Quelles sorties…

Si MongoDb n'est pas installé sur votre ordinateur, vous devez vous rendre sur le Centre de téléchargement MongoDb, télécharger et installer la version compatible avec votre système d'exploitation avant de continuer.

Nommer notre projet

Il est maintenant temps de donner un nom à notre projet et nous l'appellerons RESTHub. Nous devons trouver un bon emplacement dans notre système de fichiers pour stocker nos fichiers de projet. Personnellement, comme je travaille avec différents outils et langages de programmation, j'ai choisi de conserver mes projets basés sur les nœuds dans un répertoire nodeprojects sur mon lecteur local. C’est là que je vais créer mon nouveau resthub de répertoire de projet avec les commandes suivantes

// Naviguez jusqu'au répertoire racine de vos projets de nœud
cd C: \ nodeprojects
// Créer un répertoire pour votre nouveau projet RestHub
mkdir resthub
// Naviguer dans le répertoire
cd resthub

Initialisez le projet NodeJs avec npm init, suivez l'assistant pour configurer le projet.

Acceptez le nom et la version par défaut, mais modifiez la description comme indiqué ci-dessus. N'oubliez pas de changer le nom de l'auteur en votre nom et acceptez la licence par défaut permettant de générer package.json. Ne vous inquiétez pas de certaines entrées si vous faites une erreur, le fichier sera disponible dans le répertoire racine de votre projet pour que vous puissiez le modifier à votre guise. Vous devriez un écran semblable à celui-ci…

À ce stade, vous devez vérifier qu’un fichier package.json est disponible à la racine de votre projet en répertoriant les fichiers avec ls -l ou dir en fonction de votre système d’exploitation.

Temps d'installation Express et Setup Server

Nous devons utiliser un serveur Web afin de rendre notre point de terminaison d'API accessible au navigateur ou à un outil tel que PostMan. Pour ce faire, nous utiliserons ExpressJS. Si vous n’êtes pas familier avec ExpressJS, rendez-vous sur le site officiel pour en savoir plus, sinon continuons. Avec npm, nous installons Express dans notre projet avec cette commande

npm install express --save

L’installation prendra un certain temps en fonction de votre vitesse de connexion, mais au final, ExpressJs et ses dépendances seront installés comme indiqué ci-dessous.

Assez de toutes ces installations, assistants et configurations. Nous devons commencer à écrire du code maintenant. Le temps que vous ouvrez votre IDE préféré, le mien est le code Visual Studio.

Utilisez votre IDE préféré pour ouvrir le répertoire du projet et créer un fichier index.js

Vous pouvez voir un répertoire node_modules et un fichier package.json. Package.json stocke la configuration du projet nodeJs, y compris les dépendances. Vous pouvez voir le fichier expressjs -v4.16.3 qui vient d'être installé sous des dépendances. Les packages de nœuds installés sont situés dans node_modules et nous ne devrions rien modifier dans ce répertoire. Nous devrions plutôt exclure avec gitignore lorsque nous effectuons une migration vers un référentiel distant. Dans notre package.json, nous avons défini index.js comme point d’entrée de notre application. Nous devons créer ce fichier maintenant et configurer notre serveur Web.

Dans votre IDE, créez un fichier index.js et ajoutez ce code…

// NomFichier: index.js
// Importer express
let express = require ('express')
// Initialiser l'application
laissez app = express ();
// Port du serveur d'installation
var port = process.env.PORT || 8080;
// Envoyer un message pour l'URL par défaut
app.get ('/', (req, res) => res.send ('Hello World with Express'));
// Lancer l'application pour écouter le port spécifié
app.listen (port, fonction () {
     console.log ("Exécution de RestHub sur le port" + port);
});

Enregistrez le fichier et exécutez l'index de noeud dans la fenêtre du terminal. Vous devriez obtenir ceci

Allez sur http: // localhost: 8080 sur votre navigateur et vous devriez voir…

Hourra!!! Notre serveur express est maintenant opérationnel. Nous l'avons fait… oui! Rien n’est aussi doux que de vous permettre de vous installer sans heurts. Si vous n'obtenez pas le même résultat que le mien au point, relisez-le pour vérifier si vous avez manqué un point ou un point-virgule.

Très bien, structurons notre application de manière professionnelle. Même si je vais suivre certaines des meilleures pratiques lors de la mise en œuvre de cette démarche, je la garderai aussi simple que possible. Il s’agit d’un didacticiel pour débutants et la plupart des didacticiels que j’ai rencontrés dans le passé ont tendance à tout regrouper dans un seul fichier pour implémenter de simples API comme celle-ci. Dans le monde réel, cela n’arrive pas, surtout si votre équipe choisit une architecture telle que le modèle MVC.

Nous allons injecter un peu de MVC dans cette structure d'application pour que nos fichiers restent simples et séparés. Nous avons besoin de trois autres fichiers énumérés ci-dessous…

  • api-routes - tous les points d'extrémité api doivent être définis dans ce fichier
  • controller - traite les requêtes HTTP et définit les terminaux disponibles
  • model - gère la couche de base de données (demande et réponse)

Créez un fichier dans votre projet racine api-routes.js et ajoutez-y le code suivant.

// Nom de fichier: api-routes.js
// Initialise le routeur express
let routeur = require ('express'). Router ();
// Définir la réponse par défaut de l'API
router.get ('/', fonction (req, res) {
    res.json ({
        statut: 'API son fonctionnement',
        message: 'Bienvenue dans RESTHub conçu avec amour!'
    });
});
// Exporter les routes de l'API
module.exports = routeur;

Nous importons d’abord le routeur express, définissons la route par défaut et exportons le module afin que nous puissions importer dans notre application. Pour rendre cette route accessible, nous devons modifier index.js et lui ajouter quelques lignes de code comme ceci.

// Ajoute le code ci-dessous à index.js
// Importer des routes
let apiRoutes = require ("./ api-routes")
// Utiliser les itinéraires Api dans l'application
app.use ('/ api', apiRoutes)

redémarrez ensuite le serveur d'applications en mettant fin au processus sur votre terminal avec ctrl + c ou cmd + c et recommencez avec l'index de nœud.

Dans le code ci-dessus, nous avons importé le fichier api-routes et ordonnons à notre application d'utiliser ces routes chaque fois qu'un utilisateur visite example.com/api ou http: // localhost: 8080 / api dans notre cas. Testez si cela fonctionne en visitant http: // localhost: 8080 / api, vous devriez voir cet écran

Ouais! Ça a marché. Vous pouvez faire une pause et boire une bouteille d'eau comme je viens de le faire. Nous progressons de manière satisfaisante, mais nous devons éliminer un petit goulot d’étranglement pour que nos progrès soient plus fluides.

Notre configuration actuelle nécessite de redémarrer le serveur chaque fois que nous apportons des modifications à nos fichiers ou en ajoutons de nouveaux. Cela peut parfois devenir stressant et frustrant, mais il existe une solution rapide. Il existe un module de nœud qui fournit cette solution rapide; surveille vos fichiers et redémarre Express-Server en cas de modification. Il est préférable d'installer ce module globalement, car vous en aurez peut-être besoin dans d'autres projets.

npm installer -g nodemon
// sur Mac ou Linux
sudo npm installer -g nodemon

Maintenant que vous avez installé nodemon, démarrez plutôt votre application avec l'index nodemon, modifiez le texte de l'itinéraire par défaut à partir de Hello World avec Express et Nodemon, puis actualisez votre navigateur pour afficher les modifications.

Cool, nous n’avons pas à nous soucier de redémarrer notre serveur d’application chaque fois que nous apportons des modifications.

Configurer MongoDb

Je veux supposer que vous avez installé MongoDb sur votre ordinateur. Sinon, visitez le Centre de téléchargement Mongodb pour le télécharger et l’installer. Ouvrez une autre fenêtre de terminal et démarrez le serveur mongodb avec cette commande

Mongod

vous obtiendrez une sortie semblable à celle-ci

Laissez cette fenêtre ouverte pour pouvoir utiliser MongoDb. Rendez-vous au terminal racine de votre projet et installez ces packages

  • mangouste npm installer mangouste --save
  • analyseur de corps npm installer analyseur de corps --save

Mongoose est le paquet Nodejs pour modéliser Mongodb. Il vous aide à gérer la validation et la logique métier pour mongodb sur Nodejs. Vous pouvez en apprendre davantage ici.

Body-parser permet à votre application d'analyser les données de la requête entrante, comme les données de formulaire via urlencode. Nous devons importer cela dans notre application et les utiliser.

Modifier index.js avec ces lignes
Mise à jour: j'ai mis à jour la ligne Mongoose Connect pour ajouter l'option useNewUrlParser et résoudre l'avertissement de dépréciation

// Importer l'analyseur de corps
let bodyParser = require ('analyseur de corps');
// Importer Mongoose
laisser la mangouste = require ('mangouste');
// Configurer Bodyparser pour gérer les demandes de publication
app.use (bodyParser.urlencoded ({
   étendu: vrai
}));
app.use (bodyParser.json ());
// Se connecter à Mongoose et définir une variable de connexion
// Obsolète: mongoose.connect ('mongodb: // localhost / resthub');
mongoose.connect ('mongodb: // localhost / resthub', {useNewUrlParser: true});
var db = mongoose.connection;

Votre index.js complet devrait ressembler à ceci

// Importer express
let express = require ('express');
// Importer l'analyseur de corps
let bodyParser = require ('analyseur de corps');
// Importer Mongoose
laisser la mangouste = require ('mangouste');
// Initialise l'application
laissez app = express ();

// Importer des routes
let apiRoutes = require ("./ api-routes");
// Configurer Bodyparser pour gérer les demandes de publication
app.use (bodyParser.urlencoded ({
    étendu: vrai
}));
app.use (bodyParser.json ());
// Se connecter à Mongoose et définir une variable de connexion
mongoose.connect ('mongodb: // localhost / resthub', {useNewUrlParser: true});
var db = mongoose.connection;

// Ajout d'une vérification pour la connexion à la base de données
si (! db)
    console.log ("Erreur de connexion à la base de données")
autre
    console.log ("Db connecté avec succès")

// Port du serveur d'installation
var port = process.env.PORT || 8080;

// Envoyer un message pour l'URL par défaut
app.get ('/', (req, res) => res.send ('Hello World with Express'));

// Utiliser les itinéraires Api dans l'application
app.use ('/ api', apiRoutes);
// Lancer l'application pour écouter le port spécifié
app.listen (port, fonction () {
    console.log ("Exécution de RestHub sur le port" + port);
});

Tout devrait bien fonctionner. Il est maintenant temps de configurer notre contrôleur pour gérer la demande d'API et de créer un modèle pour enregistrer / récupérer les données de la base de données. Nous allons implémenter un modèle de données simple pour stocker les informations de contact avec les détails suivants:

  • Nom
  • Email
  • Téléphone
  • Le sexe HOMME ou FEMME

Nous allons implémenter les points de terminaison suivants

  • GET / api / liste de tous les contacts
  • POST / api / contacts créer un nouveau contact
  • GET / api / contacts / {id} récupérer un seul contact
  • PUT / api / contacts / {id} met à jour un seul contact
  • DELETE / api / contacts / {id} supprime un seul contact

Nous allons à deux (2) fichiers supplémentaires contactController.js et contactModel.js et coller ces codes.

// contactController.js
// Importer un modèle de contact
Contact = require ('./ contactModel');
// Gérer les actions d'index
exports.index = fonction (req, res) {
    Contact.get (fonction (err, contacts) {
        si (err) {
            res.json ({
                statut: "erreur",
                message: err,
            });
        }
        res.json ({
            statut: "succès",
            message: "Contacts récupérés avec succès",
            données: contacts
        });
    });
};
// Gestion des actions de création de contact
exports.new = fonction (req, res) {
    var contact = new Contact ();
    contact.name = req.body.name? req.body.name: contact.name;
    contact.gender = req.body.gender;
    contact.email = req.body.email;
    contact.phone = req.body.phone;
// enregistre le contact et vérifie les erreurs
    contact.save (function (err) {
        // if (err)
        // res.json (err);
res.json ({
            message: 'Nouveau contact créé!',
            données: contact
        });
    });
};
// Gérer les informations de contact
exports.view = fonction (req, res) {
    Contact.findById (req.params.contact_id, function (err, contact) {
        si (err)
            res.send (err);
        res.json ({
            message: 'Chargement des coordonnées en cours ..',
            données: contact
        });
    });
};
// Gestion des informations de contact de mise à jour
exports.update = fonction (req, res) {
Contact.findById (req.params.contact_id, function (err, contact) {
        si (err)
            res.send (err);
contact.name = req.body.name? req.body.name: contact.name;
        contact.gender = req.body.gender;
        contact.email = req.body.email;
        contact.phone = req.body.phone;
// enregistre le contact et vérifie les erreurs
        contact.save (function (err) {
            si (err)
                res.json (err);
            res.json ({
                message: 'Informations de contact mises à jour',
                données: contact
            });
        });
    });
};
// Gère le contact de suppression
exports.delete = function (req, res) {
    Contact.remove ({
        _id: req.params.contact_id
    }, fonction (err, contact) {
        si (err)
            res.send (err);
res.json ({
            statut: "succès",
            message: 'Contact supprimé'
        });
    });
};

Le contrôleur a défini la méthode qui gère la demande et la réponse de différents points de terminaison d'API. Nous importons d’abord le contactModel et utilisons son instance pour gérer les fonctions CRUD (Créer, Récupérer, Mettre à jour et Supprimer) de l’API. Voici le code pour le contactModel.js

// contactModel.js
var mangouste = require ('mangouste');
// schéma d'installation
var contactSchema = mongoose.Schema ({
    Nom: {
        type: chaîne,
        requis: vrai
    },
    email: {
        type: chaîne,
        requis: vrai
    },
    sexe: chaîne,
    téléphone: String,
    créer un rendez-vous: {
        type: date,
        défaut: Date.now
    }
});
// Modèle de contact d'exportation
var Contact = module.exports = mongoose.model ('contact', contactSchema);
module.exports.get = fonction (rappel, limite) {
    Contact.find (rappel) .limit (limite);
}

Dans le modèle, nous importons Mangoose, avons créé le schéma de base de données pour les contacts et avons exporté le module pour le rendre accessible. La dernière mise à jour ajoutera des itinéraires de contact à nos points de terminaison api. Voici le code complet pour api-routes.js

// api-routes.js
// Initialise le routeur express
let routeur = require ('express'). Router ();
// Définir la réponse par défaut de l'API
router.get ('/', fonction (req, res) {
    res.json ({
        statut: 'API son fonctionnement',
        message: 'Bienvenue dans RESTHub conçu avec amour!',
    });
});
// Importer le contrôleur de contact
var contactController = require ('./ contactController');
// itinéraires de contact
router.route ('/ contacts')
    .get (contactController.index)
    .post (contactController.new);
router.route ('/ contacts /: contact_id')
    .get (contactController.view)
    .patch (contactController.update)
    .put (contactController.update)
    .delete (contactController.delete);
// Exporter les routes de l'API
module.exports = routeur;

Hou la la! Ce fut un très long trajet. Nous avons terminé la cuisson et il est temps de tester nos points finaux d'api.

Essayons avec le navigateur. Visitez http: // localhost: 8080 / api / contacts, vous devriez obtenir cet écran

Cela semble bon. Nous n'avons pas encore de contacts dans notre collection. Nous devons y ajouter quelques contacts. Postman est un très bon outil pour tester et déboguer les points de terminaison d'API. Si vous en avez un sur votre ordinateur, procurez-vous-le ici. On dirait…

Je viens de tester le / api / contacts sur Postman et j'ai le même résultat.

Il prend également en charge une longue liste de types de demandes, notamment HTTP GET, POST, PUT, DELETE.

Pour ajouter un nouveau contact, modifiez la méthode du menu déroulant à POST, sélectionnez l'onglet Corps, indiquez les valeurs des zones de saisie clé: valeur sous l'onglet Corps, puis cliquez sur Envoyer lorsque vous avez terminé. Voir exemple ci-dessous:

Modifiez les valeurs pour créer un autre contact. Ouvrez un autre onglet et utilisez la demande GET pour afficher tous les contacts de la même manière.

Actualisez votre navigateur pour voir s'il a été mis à jour. Vous devriez obtenir cet écran.

Bon les gars, nous sommes arrivés à la fin de notre longue session. Allez-y et essayez de mettre à jour et supprimer. Essayez de construire quelque chose de cool et de répandre l'évangile. Vous pouvez m'attraper sur twitter, facebook, github et linkedin via @dinyangetoh

Oh, j'ai failli oublier d'ajouter le lien github pour les fichiers source. N'hésitez pas à le cloner ici et à vous amuser à créer des applications étonnantes.

Liens mis à jour:

Application Heroku: https://resthub2.herokuapp.com

Github: https://github.com/dinyangetoh/resthub2