Créer une API REST avec Node.js et Express :Connecter une base de données
Dans le premier didacticiel, Comprendre les API RESTful, nous avons appris ce qu'est l'architecture REST, quelles sont les méthodes de requête HTTP et les réponses, et comment comprendre un point de terminaison d'API RESTful. Dans le deuxième didacticiel, Comment configurer un serveur d'API Express, nous avons appris à créer des serveurs avec le http
intégré de Node. module et le framework Express, et comment acheminer l'application que nous avons créée vers différents points de terminaison d'URL.
Actuellement, nous utilisons des données statiques pour afficher les informations utilisateur sous la forme d'un flux JSON lorsque le point de terminaison de l'API est atteint avec un GET
demande. Dans ce didacticiel, nous allons configurer une base de données MySQL pour stocker toutes les données, nous connecter à la base de données à partir de notre application Node.js et autoriser l'API à utiliser le GET
, POST
, PUT
, et DELETE
méthodes pour créer une API complète.
Installation
Jusqu'à présent, nous n'avons pas utilisé de base de données pour stocker ou manipuler des données, nous allons donc en créer une. Ce tutoriel utilisera MySQL, et si MySQL est déjà installé sur votre ordinateur, vous serez prêt à passer à l'étape suivante.
Si vous n'avez pas installé MySQL, vous pouvez télécharger MAMP pour macOS et Windows, qui fournit un environnement de serveur local gratuit et une base de données. Une fois que vous l'avez téléchargé, ouvrez le programme et cliquez sur Démarrer les serveurs pour démarrer MySQL.
En plus de configurer MySQL lui-même, nous voudrons qu'un logiciel graphique affiche la base de données et les tables. Pour Mac, téléchargez SequelPro et pour Windows, téléchargez SQLyog. Une fois MySQL téléchargé et exécuté, vous pouvez utiliser SequelPro ou SQLyog pour vous connecter à localhost
avec le nom d'utilisateur root
et mot de passe root
sur le port 3306
.
Une fois que tout est configuré ici, nous pouvons passer à la configuration de la base de données pour notre API.
Configuration de la base de données
Dans votre logiciel de visualisation de base de données, ajoutez une nouvelle base de données et appelez-la api
. Assurez-vous que MySQL est en cours d'exécution, sinon vous ne pourrez pas vous connecter à localhost
.
Lorsque vous avez l'api
base de données créée, accédez-y et exécutez la requête suivante pour créer une nouvelle table.
CREATE TABLE `users` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(30) DEFAULT '', `email` varchar(50) DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Cette requête SQL va créer la structure de nos users
table. Chaque utilisateur aura un identifiant auto-incrémenté, un nom et une adresse e-mail.
Nous pouvons également remplir la base de données avec les mêmes données que celles que nous affichons actuellement via un tableau JSON statique en exécutant un INSERT
requête.
INSERT INTO users (name, email) VALUES ('Richard Hendricks', '[email protected]'), ('Bertram Gilfoyle', '[email protected]');
Il n'est pas nécessaire de saisir le id
champ, car il s'incrémente automatiquement. À ce stade, nous avons la structure de notre tableau ainsi que des exemples de données avec lesquels travailler.
Connexion à MySQL
De retour dans notre application, nous devons nous connecter à MySQL à partir de Node.js pour commencer à travailler avec les données. Plus tôt, nous avons installé le mysql
module npm, et maintenant nous allons l'utiliser.
Créez un nouveau répertoire appelé data et faites un config.js fichier.
Nous allons commencer par exiger le mysql
module dans data/config.js .
const mysql = require('mysql');
Créons une config
objet qui contient l'hôte, l'utilisateur, le mot de passe et la base de données. Cela devrait faire référence à l'api
base de données que nous avons créée et utiliser les paramètres localhost par défaut.
// Set database connection credentials const config = { host: 'localhost', user: 'root', password: 'root', database: 'api', };
Pour plus d'efficacité, nous allons créer un pool MySQL, ce qui nous permet d'utiliser plusieurs connexions à la fois au lieu d'avoir à ouvrir et fermer manuellement plusieurs connexions.
// Create a MySQL pool const pool = mysql.createPool(config);
Enfin, nous allons exporter le pool MySQL afin que l'application puisse l'utiliser.
// Export the pool module.exports = pool;
Vous pouvez voir le fichier de configuration de la base de données terminé dans notre dépôt GitHub.
Maintenant que nous nous connectons à MySQL et que nos paramètres sont terminés, nous pouvons passer à l'interaction avec la base de données à partir de l'API.
Obtenir des données d'API à partir de MySQL
Actuellement, notre routes.js
Le fichier crée manuellement un tableau JSON d'utilisateurs, qui ressemble à ceci.
const users = [{ ...
Puisque nous n'utiliserons plus de données statiques, nous pouvons supprimer tout ce tableau et le remplacer par un lien vers notre pool MySQL.
// Load the MySQL pool connection const pool = require('../data/config');
Auparavant, le GET
pour les /users
path envoyait les users
statiques Les données. Notre code mis à jour va plutôt interroger la base de données pour ces données. Nous allons utiliser une requête SQL pour SELECT
tous des users
tableau, qui ressemble à ceci.
SELECT * FROM users
Voici ce que nos nouveaux /users
get route ressemblera, en utilisant le pool.query()
méthode.
// Display all users app.get('/users', (request, response) => { pool.query('SELECT * FROM users', (error, result) => { if (error) throw error; response.send(result); }); });
Ici, nous exécutons le SELECT
requête puis envoi du résultat au format JSON au client via le /users
point final. Si vous redémarrez le serveur et accédez à /users
page, vous verrez les mêmes données qu'avant, mais maintenant elles sont dynamiques.
Utilisation des paramètres d'URL
Jusqu'à présent, nos points de terminaison étaient des chemins statiques, soit le /
root ou /users
— mais qu'en est-il lorsque nous voulons voir uniquement les données d'un utilisateur spécifique ? Nous devrons utiliser un point de terminaison variable.
Pour nos utilisateurs, nous souhaitons peut-être récupérer des informations sur chaque utilisateur individuel en fonction de son identifiant unique. Pour ce faire, nous utiliserions deux-points (:
) pour indiquer qu'il s'agit d'un paramètre de route.
// Display a single user by ID app.get('/users/:id', (request, response) => { ... }); });
Nous pouvons récupérer le paramètre de ce chemin avec le request.params
biens. Puisque le nôtre s'appelle id
, c'est ainsi que nous l'appellerons.
const id = request.params.id;
Nous allons maintenant ajouter un WHERE
clause à notre SELECT
déclaration pour obtenir uniquement les résultats qui ont le id
spécifié .
Nous utiliserons ?
en tant qu'espace réservé pour éviter l'injection SQL et transmettre l'identifiant en tant que paramètre, au lieu de créer une chaîne concaténée, ce qui serait moins sécurisé.
pool.query('SELECT * FROM users WHERE id = ?', id, (error, result) => { if (error) throw error; response.send(result); });
Le code complet de notre ressource utilisateur individuelle ressemble maintenant à ceci :
// Display a single user by ID app.get('/users/:id', (request, response) => { const id = request.params.id; pool.query('SELECT * FROM users WHERE id = ?', id, (error, result) => { if (error) throw error; response.send(result); }); });
Vous pouvez maintenant redémarrer le serveur et accéder à https://localhost/users/2
pour ne voir que les informations de Gilfoyle. Si vous obtenez une erreur du type Cannot GET /users/2
, cela signifie que vous devez redémarrer le serveur.
Aller à cette URL devrait renvoyer un seul résultat.
[{ id: 2, name: "Bertram Gilfoyle", email: "[email protected]" }]
Si c'est ce que vous voyez, félicitations :vous avez configuré avec succès un paramètre de routage dynamique !
Envoi d'une requête POST
Jusqu'à présent, tout ce que nous avons fait a utilisé GET
demandes. Ces requêtes sont sûres, c'est-à-dire qu'elles ne modifient pas l'état du serveur. Nous avons simplement visualisé les données JSON.
Nous allons maintenant commencer à rendre l'API vraiment dynamique en utilisant un POST
demande d'ajout de nouvelles données.
J'ai mentionné plus tôt dans l'article Comprendre REST que nous n'utilisons pas de verbes comme add
ou delete
dans l'URL pour effectuer des actions. Afin d'ajouter un nouvel utilisateur à la base de données, nous allons POST
à la même URL à partir de laquelle nous les visualisons, mais configurez simplement une route distincte pour cela.
// Add a new user app.post('/users', (request, response) => { ... });
Notez que nous utilisons app.post()
au lieu de app.get()
maintenant.
Puisque nous créons au lieu de lire, nous utiliserons un INSERT
requête ici, un peu comme nous l'avons fait lors de l'initialisation de la base de données. Nous enverrons l'intégralité de la request.body
jusqu'à la requête SQL.
pool.query('INSERT INTO users SET ?', request.body, (error, result) => { if (error) throw error;
Nous allons également spécifier le statut de la réponse en tant que 201
, qui signifie Created
. Afin d'obtenir l'identifiant du dernier élément inséré, nous utiliserons le insertId
propriété.
response.status(201).send(`User added with ID: ${result.insertId}`);
L'intégralité de notre POST
le code de réception ressemblera à ceci.
// Add a new user app.post('/users', (request, response) => { pool.query('INSERT INTO users SET ?', request.body, (error, result) => { if (error) throw error; response.status(201).send(`User added with ID: ${result.insertId}`); }); });
Nous pouvons maintenant envoyer un POST
demande à travers. La plupart du temps, lorsque vous envoyez un POST
demande, vous le faites via un formulaire Web. Nous apprendrons comment configurer cela à la fin de cet article, mais le moyen le plus rapide et le plus simple d'envoyer un test POST
est avec cURL, en utilisant le -d (--data)
drapeau.
Nous allons exécuter curl -d
, suivi d'une chaîne de requête contenant toutes les paires clé/valeur et le point de terminaison de la requête.
curl -d "name=Dinesh Chugtai&[email protected]" http://localhost:3002/users
Une fois que vous avez envoyé cette requête, vous devriez obtenir une réponse du serveur.
User added with ID: 3
Si vous accédez à http://localhost/users
, vous verrez la dernière entrée ajoutée à la liste.
Envoi d'une requête PUT
POST
est utile pour ajouter un nouvel utilisateur, mais nous voudrons utiliser PUT
pour modifier un utilisateur existant. PUT
est idempotent, ce qui signifie que vous pouvez envoyer la même requête plusieurs fois et qu'une seule action sera effectuée. Ceci est différent de POST
, car si nous envoyions notre nouvelle demande d'utilisateur plusieurs fois, cela continuerait à créer de nouveaux utilisateurs.
Pour notre API, nous allons configurer PUT
pour pouvoir gérer l'édition d'un seul utilisateur, nous allons donc utiliser le :id
paramètre de route cette fois.
Créons une UPDATE
requête et assurez-vous qu'elle ne s'applique qu'à l'identifiant demandé avec le WHERE
clause. Nous utilisons deux ?
espaces réservés, et les valeurs que nous transmettons iront dans un ordre séquentiel.
// Update an existing user app.put('/users/:id', (request, response) => { const id = request.params.id; pool.query('UPDATE users SET ? WHERE id = ?', [request.body, id], (error, result) => { if (error) throw error; response.send('User updated successfully.'); }); });
Pour notre test, nous allons modifier l'utilisateur 2
et mettez à jour l'adresse e-mail de [email protected] à [email protected]. Nous pouvons à nouveau utiliser cURL, avec le [-X (--request)]
flag, pour spécifier explicitement que nous envoyons une requête PUT via.
curl -X PUT -d "name=Bertram Gilfoyle" -d "[email protected]" http://localhost:3002/users/2
Assurez-vous de redémarrer le serveur avant d'envoyer la requête, sinon vous obtiendrez le message Cannot PUT /users/2
erreur.
Vous devriez voir ceci :
User updated successfully.
Les données utilisateur avec l'identifiant 2
devrait maintenant être mis à jour.
Envoi d'une demande de suppression
Notre dernière tâche pour compléter la fonctionnalité CRUD de l'API est de créer une option pour supprimer un utilisateur de la base de données. Cette requête utilisera le DELETE
Requête SQL avec WHERE
, et il supprimera un utilisateur individuel spécifié par un paramètre de route.
// Delete a user app.delete('/users/:id', (request, response) => { const id = request.params.id; pool.query('DELETE FROM users WHERE id = ?', id, (error, result) => { if (error) throw error; response.send('User deleted.'); }); });
Nous pouvons utiliser -X
à nouveau avec cURL pour envoyer la suppression. Supprimons le dernier utilisateur que nous avons créé.
curl -X DELETE http://localhost:3002/users/3
Vous verrez le message de réussite.
User deleted.
Accédez à http://localhost:3002
, et vous verrez qu'il n'y a plus que deux utilisateurs maintenant.
Toutes nos félicitations! À ce stade, l'API est terminée. Visitez le dépôt GitHub pour voir le code complet de routes.js .
Envoi de requêtes via la request
Module
Au début de cet article, nous avons installé quatre dépendances, et l'une d'elles était la request
module. Au lieu d'utiliser des requêtes cURL, vous pouvez créer un nouveau fichier avec toutes les données et l'envoyer. Je vais créer un fichier appelé post.js qui créera un nouvel utilisateur via POST
.
const request = require('request'); const json = { "name": "Dinesh Chugtai", "email": "[email protected]", }; request.post({ url: 'http://localhost:3002/users', body: json, json: true, }, function (error, response, body) { console.log(body); });
Nous pouvons appeler cela en utilisant node post.js
dans une nouvelle fenêtre de terminal pendant que le serveur est en cours d'exécution, et cela aura le même effet que l'utilisation de cURL. Si quelque chose ne fonctionne pas avec cURL, la request
module est utile car nous pouvons voir l'erreur, la réponse et le corps.
Envoi de demandes via un formulaire Web
Généralement, POST
et d'autres méthodes HTTP qui modifient l'état du serveur sont envoyées à l'aide de formulaires HTML. Dans cet exemple très simple, nous pouvons créer un index.html déposer n'importe où et créer un champ pour un nom et une adresse e-mail. L'action du formulaire pointera vers la ressource, dans ce cas http//localhost:3002/users
, et nous spécifierons la méthode comme post
.
Créer index.html et ajoutez-y le code suivant :
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Node.js Express REST API</title> </head> <body> <form action="http://localhost:3002/users" method="post"> <label for="name">Name</label> <input type="text" name="name"> <label for="email">Email</label> <input type="email" name="email"> <input type="submit"> </form> </body> </html>
Ouvrez ce fichier HTML statique dans votre navigateur, remplissez-le et envoyez-le pendant que le serveur est en cours d'exécution dans le terminal. Vous devriez voir la réponse de User added with ID: 4
, et vous devriez pouvoir afficher la nouvelle liste d'utilisateurs.