Codieren Sie Ihre erste API mit Node.js und Express: Verbinden Sie eine Datenbank
() translation by (you can also view the original English article)
Erstellen Sie eine REST-API mit Node.js und Express: Verbinden einer Datenbank
Im ersten Tutorial, Grundlegendes zu RESTful-API, haben wir die REST-Architektur, die HTTP-Anforderungsmethoden und -antworten sowie das Verständnis eines RESTful-API-Endpunkts kennengelernt. Im zweiten Tutorial, Einrichten eines Express-API-Servers, haben wir gelernt, wie Server mit dem integrierten http
-Modul von Node und dem Express-Framework erstellt werden und wie die von uns erstellte App an verschiedene URL-Endpunkte weitergeleitet wird.
Derzeit verwenden wir statische Daten, um Benutzerinformationen in Form eines JSON-Feeds anzuzeigen, wenn der API-Endpunkt von einer GET
-Anforderung getroffen wird. In diesem Tutorial richten wir eine MySQL-Datenbank ein, in der alle Daten gespeichert, über unsere Node.js-App eine Verbindung zur Datenbank hergestellt und der API ermöglicht wird, mithilfe der Methoden GET
, POST
, PUT
und DELETE
eine zu erstellen vollständige API.
Installation
Bis zu diesem Zeitpunkt haben wir keine Datenbank zum Speichern oder Bearbeiten von Daten verwendet, daher werden wir eine einrichten. In diesem Tutorial wird MySQL verwendet. Wenn Sie MySQL bereits auf Ihrem Computer installiert haben, können Sie mit dem nächsten Schritt fortfahren.
Wenn Sie MySQL nicht installiert haben, können Sie MAMP für macOS und Windows herunterladen, das eine kostenlose lokale Serverumgebung und Datenbank bietet. Sobald Sie dies heruntergeladen haben, öffnen Sie das Programm und klicken Sie auf Server starten, um MySQL zu starten.
Zusätzlich zum Einrichten von MySQL selbst soll die GUI-Software die Datenbank und die Tabellen anzeigen. Laden Sie für Mac SequelPro und für Windows SQLyog herunter. Sobald Sie MySQL heruntergeladen und ausgeführt haben, können Sie SequelPro oder SQLyog verwenden, um eine Verbindung zu localhost
mit dem Benutzernamen root
und dem Passwort root
an Port 3306
herzustellen.
Sobald hier alles eingerichtet ist, können wir mit dem Einrichten der Datenbank für unsere API fortfahren.
Einrichten der Datenbank
Fügen Sie in Ihrer Datenbankanzeigesoftware eine neue Datenbank hinzu und nennen Sie sie api
. Stellen Sie sicher, dass MySQL ausgeführt wird, da Sie sonst keine Verbindung zu localhost
herstellen können.
Wenn Sie die api
-Datenbank erstellt haben, verschieben Sie sie und führen Sie die folgende Abfrage aus, um eine neue Tabelle zu erstellen.
1 |
CREATE TABLE `users` ( |
2 |
`id` int(11) unsigned NOT NULL AUTO_INCREMENT, |
3 |
`name` varchar(30) DEFAULT '', |
4 |
`email` varchar(50) DEFAULT '', |
5 |
PRIMARY KEY (`id`) |
6 |
) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
Diese SQL-Abfrage erstellt die Struktur unserer users
-Tabelle. Jeder Benutzer hat eine automatisch inkrementierende ID, einen Namen und eine E-Mail-Adresse.
Wir können die Datenbank auch mit denselben Daten füllen, die wir derzeit über ein statisches JSON-Array anzeigen, indem wir eine INSERT
-Abfrage ausführen.
1 |
INSERT INTO users (name, email) |
2 |
VALUES ('Richard Hendricks', 'richard@piedpiper.com'), |
3 |
('Bertram Gilfoyle', 'gilfoyle@piedpiper.com'); |
Das id
-Feld muss nicht eingegeben werden, da es automatisch inkrementiert wird. Zu diesem Zeitpunkt haben wir die Struktur unserer Tabelle sowie einige Beispieldaten, mit denen wir arbeiten können.
Verbindung zu MySQL herstellen
Zurück in unserer App müssen wir von Node.js aus eine Verbindung zu MySQL herstellen, um mit den Daten arbeiten zu können. Früher haben wir das mysql
npm-Modul installiert und jetzt werden wir es verwenden.
Erstellen Sie ein neues Verzeichnis mit dem Namen data und erstellen Sie eine config.js-Datei.
Zunächst benötigen wir das mysql
-Modul in data/config.js.
1 |
const mysql = require('mysql'); |
Erstellen wir ein config
-Objekt, das den Host, den Benutzer, das Kennwort und die Datenbank enthält. Dies sollte sich auf die von uns erstellte api
-Datenbank beziehen und die Standardeinstellungen für localhost verwenden.
1 |
// Set database connection credentials
|
2 |
const config = { |
3 |
host: 'localhost', |
4 |
user: 'root', |
5 |
password: 'root', |
6 |
database: 'api', |
7 |
};
|
Aus Effizienzgründen erstellen wir einen MySQL-Pool, mit dem wir mehrere Verbindungen gleichzeitig verwenden können, anstatt mehrere Verbindungen manuell öffnen und schließen zu müssen.
1 |
// Create a MySQL pool
|
2 |
const pool = mysql.createPool(config); |
Schließlich exportieren wir den MySQL-Pool, damit die App ihn verwenden kann.
1 |
// Export the pool
|
2 |
module.exports = pool; |
Sie können die fertige Datenbankkonfigurationsdatei in unserem GitHub-Repo sehen.
Nachdem wir uns mit MySQL verbunden haben und unsere Einstellungen abgeschlossen sind, können wir über die API mit der Datenbank interagieren.
Abrufen von API-Daten von MySQL
Derzeit erstellt unsere Datei routes.js
manuell ein JSON-Array von Benutzern, das so aussieht.
1 |
const users = [{ ... |
Da wir keine statischen Daten mehr verwenden, können wir das gesamte Array löschen und durch einen Link zu unserem MySQL-Pool ersetzen.
1 |
// Load the MySQL pool connection
|
2 |
const pool = require('../data/config'); |
Zuvor sendete das GET
für den Pfad /users
die statischen users
-Daten. Unser aktualisierter Code wird stattdessen die Datenbank nach diesen Daten abfragen. Wir verwenden eine SQL-Abfrage für SELECT
all aus der Tabelle users
, die wie folgt aussieht.
1 |
SELECT * FROM users |
So sieht die Route unserer neuen /users
aus, die die Methode pool.query()
verwendet.
1 |
// Display all users
|
2 |
app.get('/users', (request, response) => { |
3 |
pool.query('SELECT * FROM users', (error, result) => { |
4 |
if (error) throw error; |
5 |
|
6 |
response.send(result); |
7 |
});
|
8 |
});
|
Hier führen wir die SELECT
-Abfrage aus und senden das Ergebnis dann als JSON über den Endpunkt /users
an den Client. Wenn Sie den Server neu starten und zur Seite /users
navigieren, werden dieselben Daten wie zuvor angezeigt, aber jetzt sind sie dynamisch.
Verwenden von URL-Parametern
Bisher waren unsere Endpunkte statische Pfade - entweder /
-Root oder /users
-, aber was ist, wenn wir nur Daten über einen bestimmten Benutzer anzeigen möchten? Wir müssen einen variablen Endpunkt verwenden.
Für unsere Benutzer möchten wir möglicherweise Informationen zu jedem einzelnen Benutzer basierend auf seiner eindeutigen ID abrufen. Dazu verwenden wir einen Doppelpunkt (:
), um anzuzeigen, dass es sich um einen Routenparameter handelt.
1 |
// Display a single user by ID
|
2 |
app.get('/users/:id', (request, response) => { |
3 |
...
|
4 |
});
|
5 |
});
|
Wir können den Parameter für diesen Pfad mit der Eigenschaft request.params
abrufen. Da unsere id
heißt, beziehen wir uns so darauf.
1 |
const id = request.params.id; |
Jetzt fügen wir unserer SELECT
-Anweisung eine WHERE
-Klausel hinzu, um nur Ergebnisse mit der angegebenen id
zu erhalten.
Wir werden ?
als Platzhalter verwenden, um SQL-Injection zu vermeiden und die ID als Parameter zu übergeben, anstatt eine verkettete Zeichenfolge zu erstellen, die weniger sicher wäre.
1 |
pool.query('SELECT * FROM users WHERE id = ?', id, (error, result) => { |
2 |
if (error) throw error; |
3 |
|
4 |
response.send(result); |
5 |
});
|
Der vollständige Code für unsere individuelle Benutzerressource sieht nun folgendermaßen aus:
1 |
// Display a single user by ID
|
2 |
app.get('/users/:id', (request, response) => { |
3 |
const id = request.params.id; |
4 |
|
5 |
pool.query('SELECT * FROM users WHERE id = ?', id, (error, result) => { |
6 |
if (error) throw error; |
7 |
|
8 |
response.send(result); |
9 |
});
|
10 |
});
|
Jetzt können Sie den Server neu starten und zu https://localhost/users/2
navigieren, um nur die Informationen für Gilfoyle anzuzeigen. Wenn Sie eine Fehlermeldung wie Cannot GET /users/2
erhalten, müssen Sie den Server neu starten.
Wenn Sie zu dieser URL gehen, sollte ein einzelnes Ergebnis zurückgegeben werden.
1 |
[{ |
2 |
id: 2, |
3 |
name: "Bertram Gilfoyle", |
4 |
email: "gilfoyle@piedpiper.com" |
5 |
}] |
Wenn Sie das sehen, herzlichen Glückwunsch: Sie haben erfolgreich einen dynamischen Routenparameter eingerichtet!
Senden einer POST-Anfrage
Bisher wurden bei allem, was wir getan haben, GET
-Anforderungen verwendet. Diese Anforderungen sind sicher, dh sie ändern den Status des Servers nicht. Wir haben einfach JSON-Daten angezeigt.
Jetzt werden wir beginnen, die API wirklich dynamisch zu gestalten, indem wir eine POST
-Anforderung verwenden, um neue Daten hinzuzufügen.
Ich habe bereits im Artikel "REST verstehen" erwähnt, dass wir keine Verben wie add
oder delete
in der URL verwenden, um Aktionen auszuführen. Um der Datenbank einen neuen Benutzer hinzuzufügen, veröffentlichen wir POST
unter derselben URL, unter der wir sie anzeigen, richten jedoch einfach eine separate Route dafür ein.
1 |
// Add a new user
|
2 |
app.post('/users', (request, response) => { |
3 |
...
|
4 |
});
|
Beachten Sie, dass wir jetzt app.post()
anstelle von app.get()
verwenden.
Da wir erstellen anstatt zu lesen, verwenden wir hier eine INSERT
-Abfrage, ähnlich wie bei der Initialisierung der Datenbank. Wir senden die gesamte request.body
an die SQL-Abfrage.
1 |
pool.query('INSERT INTO users SET ?', request.body, (error, result) => { |
2 |
if (error) throw error; |
Wir werden auch den Status der Antwort als 201
angeben, was für Created
steht. Um die ID des zuletzt eingefügten Elements abzurufen, verwenden wir die Eigenschaft insertId
.
1 |
response.status(201).send(`User added with ID: ${result.insertId}`); |
Unser gesamter POST
-Empfangscode sieht folgendermaßen aus.
1 |
// Add a new user
|
2 |
app.post('/users', (request, response) => { |
3 |
pool.query('INSERT INTO users SET ?', request.body, (error, result) => { |
4 |
if (error) throw error; |
5 |
|
6 |
response.status(201).send(`User added with ID: ${result.insertId}`); |
7 |
});
|
8 |
});
|
Jetzt können wir eine POST
-Anfrage durch senden. Wenn Sie eine POST
-Anfrage senden, geschieht dies meistens über ein Webformular. Wir werden am Ende dieses Artikels lernen, wie man das einrichtet, aber der schnellste und einfachste Weg, einen Test-POST
zu senden, ist mit cURL unter Verwendung des Flags -d (--data)
.
Wir führen curl -d
aus, gefolgt von einer Abfragezeichenfolge, die alle Schlüssel / Wert-Paare und den Anforderungsendpunkt enthält.
1 |
curl -d "name=Dinesh Chugtai&email=dinesh@piedpiper.com" http://localhost:3002/users |
Sobald Sie diese Anfrage gesendet haben, sollten Sie eine Antwort vom Server erhalten.
1 |
User added with ID: 3 |
Wenn Sie zu http://localhost/users
navigieren, wird der neueste Eintrag zur Liste hinzugefügt.
Senden einer PUT-Anfrage
POST
ist nützlich, um einen neuen Benutzer hinzuzufügen, aber wir möchten PUT
verwenden, um einen vorhandenen Benutzer zu ändern. PUT
ist idempotent, dh Sie können dieselbe Anforderung mehrmals senden, und es wird nur eine Aktion ausgeführt. Dies unterscheidet sich von POST
, da bei einer mehrmaligen Übermittlung unserer neuen Benutzeranforderung immer wieder neue Benutzer erstellt werden.
Für unsere API richten wir PUT
so ein, dass ein einzelner Benutzer bearbeitet werden kann. Daher verwenden wir dieses Mal den Parameter :id
-Route.
Erstellen Sie eine UPDATE
-Abfrage und stellen Sie sicher, dass sie nur für die angeforderte ID mit der WHERE
-Klausel gilt. Wir benutzen zwei ?
Platzhalter und die Werte, die wir übergeben, werden nacheinander sortiert.
1 |
// Update an existing user
|
2 |
app.put('/users/:id', (request, response) => { |
3 |
const id = request.params.id; |
4 |
|
5 |
pool.query('UPDATE users SET ? WHERE id = ?', [request.body, id], (error, result) => { |
6 |
if (error) throw error; |
7 |
|
8 |
response.send('User updated successfully.'); |
9 |
});
|
10 |
});
|
Für unseren Test bearbeiten wir Benutzer 2
und aktualisieren die E-Mail-Adresse von gilfoyle@piedpiper.com auf bertram@piedpiper.com. Wir können cURL erneut mit dem Flag [-X (--request)]
verwenden, um explizit anzugeben, dass wir eine PUT-Anforderung senden.
1 |
curl -X PUT -d "name=Bertram Gilfoyle" -d "email=bertram@piedpiper.com" http://localhost:3002/users/2 |
Stellen Sie sicher, dass Sie den Server neu starten, bevor Sie die Anforderung senden. Andernfalls wird der Fehler Cannot PUT /users/2
angezeigt.
Sie sollten dies sehen:
1 |
User updated successfully. |
Die Benutzerdaten mit der ID 2
sollten jetzt aktualisiert werden.
Senden einer DELETE-Anfrage
Unsere letzte Aufgabe, um die CRUD-Funktionalität der API zu vervollständigen, besteht darin, eine Option zum Löschen eines Benutzers aus der Datenbank festzulegen. Diese Anforderung verwendet die DELETE
SQL-Abfrage mit WHERE
und löscht einen einzelnen Benutzer, der durch einen Routenparameter angegeben wird.
1 |
// Delete a user
|
2 |
app.delete('/users/:id', (request, response) => { |
3 |
const id = request.params.id; |
4 |
|
5 |
pool.query('DELETE FROM users WHERE id = ?', id, (error, result) => { |
6 |
if (error) throw error; |
7 |
|
8 |
response.send('User deleted.'); |
9 |
});
|
10 |
});
|
Wir können -X
erneut mit cURL verwenden, um das Löschen durch zu senden. Löschen wir den zuletzt erstellten Benutzer.
1 |
curl -X DELETE http://localhost:3002/users/3 |
Sie sehen die Erfolgsmeldung.
1 |
User deleted. |
Navigieren Sie zu http://localhost:3002
, und Sie werden sehen, dass es jetzt nur zwei Benutzer gibt.
Herzliche Glückwünsche! Zu diesem Zeitpunkt ist die API vollständig. Besuchen Sie das GitHub-Repo, um den vollständigen Code für route.js anzuzeigen.
Senden von Anfragen über das request
-Modul
Zu Beginn dieses Artikels haben wir vier Abhängigkeiten installiert, von denen eine das request
-Modul war. Anstatt cURL-Anforderungen zu verwenden, können Sie eine neue Datei mit allen Daten erstellen und diese senden. Ich werde eine Datei namens post.js erstellen, die einen neuen Benutzer über POST
erstellt.
1 |
const request = require('request'); |
2 |
|
3 |
const json = { |
4 |
"name": "Dinesh Chugtai", |
5 |
"email": "dinesh@piedpiper.com", |
6 |
};
|
7 |
|
8 |
request.post({ |
9 |
url: 'http://localhost:3002/users', |
10 |
body: json, |
11 |
json: true, |
12 |
}, function (error, response, body) { |
13 |
console.log(body); |
14 |
});
|
Wir können dies mit dem node post.js
in einem neuen Terminalfenster aufrufen, während der Server ausgeführt wird, und es hat den gleichen Effekt wie die Verwendung von cURL. Wenn etwas mit cURL nicht funktioniert, ist das request
-Modul hilfreich, da wir den Fehler, die Antwort und den Text anzeigen können.
Senden von Anfragen über ein Webformular
Normalerweise werden POST
- und andere HTTP-Methoden, die den Status des Servers ändern, mithilfe von HTML-Formularen gesendet. In diesem sehr einfachen Beispiel können wir überall eine index.html-Datei erstellen und ein Feld für einen Namen und eine E-Mail-Adresse erstellen. Die Aktion des Formulars verweist auf die Ressource, in diesem Fall http://localhost:3002/users
, und wir geben die Methode als post
an.
Erstellen Sie index.html und fügen Sie den folgenden Code hinzu:
1 |
<!DOCTYPE html>
|
2 |
<html lang="en"> |
3 |
|
4 |
<head>
|
5 |
<meta charset="utf-8"> |
6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
7 |
|
8 |
<title>Node.js Express REST API</title> |
9 |
</head>
|
10 |
|
11 |
<body>
|
12 |
<form action="http://localhost:3002/users" method="post"> |
13 |
<label for="name">Name</label> |
14 |
<input type="text" name="name"> |
15 |
<label for="email">Email</label> |
16 |
<input type="email" name="email"> |
17 |
<input type="submit"> |
18 |
</form>
|
19 |
</body>
|
20 |
|
21 |
</html>
|
Öffnen Sie diese statische HTML-Datei in Ihrem Browser, füllen Sie sie aus und senden Sie sie, während der Server im Terminal ausgeführt wird. Sie sollten die Antwort User added with ID: 4
hinzugefügt wurde, und Sie sollten in der Lage sein, die neue Liste der Benutzer anzuzeigen.
Abschluss
In diesem Lernprogramm haben wir gelernt, wie Sie einen Express-Server an eine MySQL-Datenbank anschließen und Routen einrichten, die den Methoden GET
, POST
, PUT
und DELETE
für Pfade und dynamische Routenparameter entsprechen. Wir haben auch gelernt, wie HTTP-Anforderungen mithilfe von cURL, dem Node.js-request
-Modul und HTML-Formularen an einen API-Server gesendet werden.
Zu diesem Zeitpunkt sollten Sie ein sehr gutes Verständnis für die Funktionsweise von RESTful-APIs haben und können jetzt Ihre eigene vollwertige API in Node.js mit Express und MySQL erstellen!