REST-API¶
Ehe wir uns weiter mit dem Frontend beschäftigen, erstellen wir einen Server, der uns die Daten liefert. Derzeit haben wir unsere Mockup-Daten noch clientseitig vom DataService
verwalten lassen und sie auch dort gespeichert. Das wollen wir nun ändern.
Wir wollen uns ein Backend erstellen, über das wir unsere Daten verwalten. Dazu überlegen wir uns zunächst ein paar Endpunkte und die Zugriffsmethoden, mit denen wir auf unsere Daten zugreifen wollen.
Methode | URL | Bedeutung |
---|---|---|
GET | /members | hole alle Datensätze |
GET | /members/11 | hole den Datensatz mit der id=11 |
POST | /members | füge einen neuen Datensatz hinzu |
PUT | /members/11 | ändere den Datensatz mit der id=11 |
DELETE | /members/11 | lösche den Datensatz mit der id=11 |
DELETE | /members | lösche alle Datensätze |
Der Wert der id
ist natürlich nur ein Beispiel. Es soll für alle id
-Werte funktionieren, die in unserem Datensatz enthalten sind.
Wir starten damit, uns ein node.js
-Projekt zu erstellen. Dazu erstellen wir uns zunächst einen Ordner backend
, wechseln in diesen Ordner und führen dann npm init
aus:
mkdir backend
cd backend
npm init
Sie werden ein paar Sachen gefragt. Im Prinzip können Sie immer Enter
drücken:
package name: (backend)
version: (1.0.0)
description: Backend REST-API MySQL
entry point: (index.js)
test command:
git repository:
keywords: restapi, express, mysql
author: J.Freiheit
license: (ISC)
About to write to /Users/jornfreiheit/Sites/WT20/backend/package.json:
{
"name": "backend",
"version": "1.0.0",
"description": "Backend REST-API MySQL",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"restapi",
"express",
"mysql"
],
"author": "J.Freiheit",
"license": "ISC"
}
Is this OK? (yes)
Die package.json
wurde erstellt. Nun benötigen wir noch ein paar nützliche Module, nämlich express
, mysql
und den body-parser
:
npm install express mysql body-parser --save
Sie erhalten eine Meldung in der Form:
+ express@4.17.1
+ body-parser@1.19.0
+ mysql@2.18.1
added 59 packages from 48 contributors and audited 60 packages in 2.016s
found 0 vulnerabilities
Öffnen Sie nun das backend
-Projekt in Ihrer IDEserver und erstellen Sie sich dort eine Datei server.js
mit folgendem Inhalt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Geben Sie im Terminal in Ihrem backend
-Ordner nun
node server.js
ein. Das müssen Sie nun leider immer wieder zum Compilieren und Ausführen machen. Sie beenden den Prozess mit Ctrl+C
und starten ihn dann erneut. Öffnen Sie im Browser http://localhost:3000/
und Sie erhalten:
Sie können auch Postman öffnen und http://localhost:3000
eintragen (GET
-Methode):
Datenbank erstellen¶
Bevor wir mit der Implementierung des Backends fortfahren, erstellen wir unsere Datenbank. Am einfachsten ist es, wenn wir phpmyadmin
unter localhost
öffnen (http://localhost/phpmyadmin
) und dort zunächst eine Datenbank anlegen (unter Neu
); benennen Sie die Datenbank am besten mockupdb
und darin folgende sql
-Datei importieren:
members.sql
-- phpMyAdmin SQL Dump
-- version 5.0.2
-- https://www.phpmyadmin.net/
--
-- Host: localhost
-- Erstellungszeit: 23. Nov 2020 um 16:23
-- Server-Version: 8.0.17
-- PHP-Version: 7.3.22-(to be removed in future macOS)
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Datenbank: `mockupdb`
--
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `members`
--
CREATE TABLE `members` (
`id` int(11) NOT NULL,
`firstname` varchar(25) NOT NULL,
`lastname` varchar(25) NOT NULL,
`email` varchar(30) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
--
-- Daten für Tabelle `members`
--
INSERT INTO `members` (`id`, `firstname`, `lastname`, `email`) VALUES
(1, 'Catherine', 'Williams', 'cwilliamsl@360.cn'),
(2, 'Adam', 'Anderson', 'aanderson8@google.fr'),
(3, 'Susan', 'Andrews', 'sandrewsn@google.co.jp'),
(4, 'Catherine', 'Andrews', 'candrewsp@noaa.gov'),
(5, 'Alan', 'Bradley', 'abradley1c@globo.com'),
(6, 'Anne', 'Brooks', 'abrooks16@bravesites.com'),
(7, 'Russell', 'Brown', 'rbrownq@nifty.com'),
(8, 'Ryan', 'Burton', 'rburton18@foxnews.com'),
(9, 'Roy', 'Campbell', 'rcampbell1@geocities.com'),
(10, 'Russell', 'Campbell', 'rcampbell17@eventbrite.com'),
(11, 'Bonnie', 'Coleman', 'bcoleman11@fc2.com'),
(12, 'Ernest', 'Coleman', 'ecoleman15@businessweek.com'),
(13, 'Richard', 'Cruz', 'rcruz7@unc.edu'),
(14, 'Sean', 'Cruz', 'scruz10@answers.com'),
(15, 'Rebecca', 'Cunningham', 'rcunninghamd@mac.com'),
(16, 'Margaret', 'Evans', 'mevansh@pcworld.com'),
(17, 'Jeffrey', 'Ford', 'jford14@cnet.com'),
(18, 'Andrea', 'Gardner', 'agardnerv@woothemes.com'),
(19, 'Deborah', 'George', 'dgeorge6@furl.net'),
(20, 'Sean', 'Gibson', 'sgibsony@alexa.com'),
(21, 'Virginia', 'Graham', 'vgrahamk@aol.com'),
(22, 'Steven', 'Hamilton', 'shamiltonu@state.tx.us'),
(23, 'Virginia', 'Hawkins', 'vhawkinsf@ehow.com'),
(24, 'Edward', 'Hicks', 'ehicksc@pcworld.com'),
(25, 'Mark', 'Johnson', 'mjohnsonj@hostgator.com'),
(26, 'Ruth', 'Jordan', 'rjordan1a@smugmug.com'),
(27, 'Antonio', 'Kim', 'akim4@odnoklassniki.ru'),
(28, 'Jennifer', 'Marshall', 'jmarshallt@gnu.org'),
(29, 'Eric', 'Matthews', 'ematthews5@independent.co.uk'),
(30, 'Raymond', 'Mcdonald', 'rmcdonald2@ihg.com'),
(31, 'Eric', 'Miller', 'emillere@creativecommons.org'),
(32, 'Jonathan', 'Morales', 'jmoralesa@ovh.net'),
(33, 'Marie', 'Morgan', 'mmorganb@cloudflare.com'),
(34, 'Amanda', 'Nelson', 'anelson13@indiatimes.com'),
(35, 'Lisa', 'Olson', 'lolsonr@telegraph.co.uk'),
(36, 'Alice', 'Ortiz', 'aortizw@histats.com'),
(37, 'Peter', 'Phillips', 'pphillipss@1688.com'),
(38, 'Matthew', 'Porter', 'mporter9@europa.eu'),
(39, 'Tammy', 'Ray', 'trayx@weather.com'),
(40, 'Mark', 'Richardson', 'mrichardson1d@ihg.com'),
(41, 'Joan', 'Roberts', 'jroberts12@alibaba.com'),
(42, 'Kathleen', 'Rose', 'kroseg@pinterest.com'),
(43, 'Steve', 'Sanders', 'ssanders1b@wikispaces.com'),
(44, 'Shirley', 'Scott', 'sscottm@macromedia.com'),
(45, 'Lillian', 'Stephens', 'lstephens19@hugedomains.com'),
(46, 'Nicole', 'Thompson', 'nthompson3@admin.ch'),
(47, 'Marie', 'Thompson', 'mthompsonz@yelp.com'),
(48, 'Alan', 'Vasquez', 'avasquezo@miibeian.gov.cn'),
(49, 'Mildred', 'Watkins', 'mwatkins0@miibeian.gov.cn'),
(50, 'Eugene', 'Williams', 'ewilliamsi@deliciousdays.com');
--
-- Indizes der exportierten Tabellen
--
--
-- Indizes für die Tabelle `members`
--
ALTER TABLE `members`
ADD PRIMARY KEY (`id`);
--
-- AUTO_INCREMENT für exportierte Tabellen
--
--
-- AUTO_INCREMENT für Tabelle `members`
--
ALTER TABLE `members`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=51;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
Falls Sie MySQL vom Studi-Server verwenden, dann müssen Sie
COLLATE=utf8mb4_0900_ai_ci
durch
COLLATE=utf8mb4_general_ci
ersetzen! Sie können sich diese Datei auch hier herunterladen. Prüfen Sie, ob alle 50 Datensätze korrekt eingelsen wurden. Unter Anzeigen
in phpmyadmin
sollte folgende Tabelle erscheinen:
Datenbank im Backend anbinden¶
Wir binden nun die Datenbank an unser Backend an. Erstellen Sie sich am besten in Ihrem backend
-Ordner einen Ordner config
und darin eine db.config.js
-Datei mit folgendem Inhalt:
module.exports = {
HOST: "localhost",
USER: "root",
PASSWORD: "IhrPasswort",
DB: "mockupdb"
};
Falls Sie MySQL des Studi-Servers verwenden, sieht die db.config.js
so aus:
module.exports = {
HOST: "db.f4.htw-berlin.de",
USER: "s05xxx",
PASSWORD: "IhrPassword",
DB: "_s05xxx__mockupdb"
};
Sie müssen Ihr Passwort eintragen und, falls Sie Ihre Datenbank anders genannt haben, auch den Datenbanknamen anpassen.
Erstellen Sie sich in Ihrem backend
-Ordner einen Ordner app
und darin einen Ordner model
. In diesem Ordner erstellen Sie sich ein db.js
, um die Verbindung zur Datenbank zu implementieren:
const mysql = require("mysql");
const dbConfig = require("../../config/db.config.js");
// Create a connection to the database
const connection = mysql.createConnection({
host: dbConfig.HOST,
user: dbConfig.USER,
password: dbConfig.PASSWORD,
database: dbConfig.DB
});
// open the MySQL connection
connection.connect(error => {
if (error) throw error;
console.log("Successfully connected to the database.");
});
module.exports = connection;
Ein Model erstellen¶
In dem app/model
-Ordner erstellen wir eine Datei members.model.js
mit folgendem Inhalt:
const sql = require("./db.js");
// constructor
const Member = function(member) {
this.firstname = member.firstname;
this.lastname = member.lastname;
this.email = member.email;
};
Member.create = (newMember, result) => {
sql.query("INSERT INTO members SET ?", newMember, (err, res) => {
if (err) {
console.log("error: ", err);
result(err, null);
return;
}
console.log("created member: ", { id: res.insertId, ...newMember });
result(null, { id: res.insertId, ...newMember });
});
};
Member.findById = (memberId, result) => {
sql.query(`SELECT * FROM members WHERE id = ${memberId}`, (err, res) => {
if (err) {
console.log("error: ", err);
result(err, null);
return;
}
if (res.length) {
console.log("found member: ", res[0]);
result(null, res[0]);
return;
}
// not found Member with the id
result({ kind: "not_found" }, null);
});
};
Member.getAll = result => {
sql.query("SELECT * FROM members", (err, res) => {
if (err) {
console.log("error: ", err);
result(null, err);
return;
}
console.log("members: ", res);
result(null, res);
});
};
Member.updateById = (id, member, result) => {
sql.query(
"UPDATE members SET firstname = ?, lastname = ?, email = ? WHERE id = ?",
[member.firstname, member.lastname, member.email, id],
(err, res) => {
if (err) {
console.log("error: ", err);
result(null, err);
return;
}
if (res.affectedRows == 0) {
// not found Customer with the id
result({ kind: "not_found" }, null);
return;
}
console.log("updated member: ", { id: id, ...member });
result(null, { id: id, ...member });
}
);
};
Member.remove = (id, result) => {
sql.query("DELETE FROM members WHERE id = ?", id, (err, res) => {
if (err) {
console.log("error: ", err);
result(null, err);
return;
}
if (res.affectedRows == 0) {
// not found Member with the id
result({ kind: "not_found" }, null);
return;
}
console.log("deleted member with id: ", id);
result(null, res);
});
};
Member.removeAll = result => {
sql.query("DELETE FROM members", (err, res) => {
if (err) {
console.log("error: ", err);
result(null, err);
return;
}
console.log(`deleted ${res.affectedRows} members`);
result(null, res);
});
};
module.exports = Member;
Die Routen definieren¶
Erstellen Sie sich im app
-Ordner einen Ordner routes
und erstellen darin eine Datei members.routes.js
mit folgendem Inhalt:
module.exports = app => {
const members = require("../controller/members.controller.js");
// Create a new Member
app.post("/members", members.create);
// GET all Members
app.get("/members", members.findAll);
// GET one single Member with memberId
app.get("/members/:memberId", members.findOne);
// Update one Member with memberId
app.put("/members/:memberId", members.update);
// Delete the Member with memberId
app.delete("/members/:memberId", members.delete);
// Delete all members
app.delete("/members", members.deleteAll);
};
Diese Datei lesen wir in unsere server.js
ein:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
Einen Controller erstellen¶
Nun erstellen wir uns im Ordner app/controller
eine members.controller.js
mit den entsprechenden CRUD-Funktionen, die wir dann noch implementieren müssen:
const Member = require("../model/members.model.js");
// Create and Save a new Member
exports.create = (req, res) => {
};
// Retrieve all Members from the database.
exports.findAll = (req, res) => {
};
// Find a single Member with a memberId
exports.findOne = (req, res) => {
};
// Update a Member identified by the memberId in the request
exports.update = (req, res) => {
};
// Delete a Member with the specified memberId in the request
exports.delete = (req, res) => {
};
// Delete all Members from the database.
exports.deleteAll = (req, res) => {
};
Überprüfen Sie Ihre Implementierung so weit, indem Sie node server.js
erneut starten. Es sollte alles ohne Fehler compilieren.
R - read all¶
Wir implementieren nun nach und nach die einzelnen Funktionen in members.controller.js
. Wir beginnen mit der findAll()
-Funktion:
8 9 10 11 12 13 14 15 16 17 18 |
|
Wenn Sie nun erneut node server.js
starten und in Postman GET http://localhost:3000/members
aufrufen, erscheinen alle Einträge aus der Datenbank:
C - create¶
Als nächstes implementieren wir die create()
-Funktion, um einen neuen Eintrag in der Datenbank anzulegen.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
Nach einem Neustart von node server.js
geben wir in Postman nun POST http://localhost:3000/members
ein und befüllen den Body
mit z.B.:
1 2 3 4 5 |
|
Achten Sie darauf, dass in der zweiten Menüzeile rechts JSON
ausgewählt ist (im Bild orange) - nicht Text
:
Wir klicken auf Send
und es erscheint:
Schauen Sie auch in Ihre Datenbank unter http://localhost/phpmyadmin
. Dort erscheint der Datensatz mit der neuen id=51
:
R - read one¶
Wir erweitern die members.controller.js
um die Funktion findOne()
, die uns für eine gegebene id
den entsprechenden Datensatz zurückliefert:
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
|
Nach Neustart des Servers geben wir in Postman z.B. GET http://localhost:3000/members/11
ein und erhalten:
Probieren Sie auch einmal GET http://localhost:3000/members/52
aus, um die Fehlermeldung als JSON zu sehen.
U - update¶
Nun noch die update()
-Funktion, um einen bereits existierenden Datensatz zu ändern:
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
|
Nach dem Neustart des Servers können wir diese Funktion in Postman ausprobieren, indem wir im Body
z.B. das JSON
1 2 3 4 5 6 |
|
mit unserem Request übergeben und PUT http://localhost:3000/members/51
wählen. Der Datensatz mit der id=51
wird dann aktualisiert:
Schauen Sie auch in der Datenbank nach und wählen auch ruhig nochmal GET http://localhost:3000/members
.
D - delete one¶
Jetzt implementieren wir noch die delete()
-Funktion, um einen Datensatz zu löschen:
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
|
Wenn wir nach dem Neustart des Servers in Postman z.B. DELETE http://localhost:3000/members/51
eingeben, erscheint:
{
"message": "Member was deleted successfully!"
}
und der Datensatz mit der id=51
ist aus der Datenbank gelöscht. Wenn wir erneut DELETE http://localhost:3000/members/51
eingeben, erscheint:
{
"message": "Not found Member with id 51."
}
Wir implementieren der Vollständigkeit halber noch die deleteAll()
-Methode. Sie können ja entscheiden, ob Sie sie ausprobieren wollen oder nicht ;-)
D - delete all¶
104 105 106 107 108 109 110 111 112 113 114 |
|
In Postman kann diese Methode mit DELETE http://localhost:3000/members/
getestet werden. Es erscheint
{
"message": "All Members were deleted successfully!"
}
und auch die Datenbank ist leer:
Sollten Sie die Methode erfolgreich ausprobiert haben, können Sie die Datenbank über diese Insert-Anweisungen wieder auffüllen (in phpmyadmin
unter dem Reiter SQL
reinkopieren):
Insert-Anweisungen für alle 50 Datensätze
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Catherine","Williams","cwilliamsl@360.cn");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Adam", "Anderson", "aanderson8@google.fr");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Susan", "Andrews", "sandrewsn@google.co.jp");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Catherine", "Andrews", "candrewsp@noaa.gov");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Alan", "Bradley", "abradley1c@globo.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Anne","Brooks","abrooks16@bravesites.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Russell","Brown","rbrownq@nifty.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Ryan","Burton","rburton18@foxnews.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Roy","Campbell","rcampbell1@geocities.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Russell","Campbell","rcampbell17@eventbrite.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Bonnie", "Coleman","bcoleman11@fc2.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Ernest","Coleman", "ecoleman15@businessweek.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Richard","Cruz","rcruz7@unc.edu");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Sean","Cruz", "scruz10@answers.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Rebecca","Cunningham","rcunninghamd@mac.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Margaret","Evans","mevansh@pcworld.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Jeffrey", "Ford", "jford14@cnet.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Andrea","Gardner", "agardnerv@woothemes.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Deborah","George", "dgeorge6@furl.net");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Sean", "Gibson", "sgibsony@alexa.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Virginia","Graham", "vgrahamk@aol.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Steven","Hamilton", "shamiltonu@state.tx.us");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Virginia", "Hawkins", "vhawkinsf@ehow.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Edward", "Hicks", "ehicksc@pcworld.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Mark", "Johnson", "mjohnsonj@hostgator.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Ruth","Jordan", "rjordan1a@smugmug.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Antonio", "Kim", "akim4@odnoklassniki.ru");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Jennifer", "Marshall", "jmarshallt@gnu.org");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Eric", "Matthews", "ematthews5@independent.co.uk");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Raymond","Mcdonald", "rmcdonald2@ihg.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Eric","Miller", "emillere@creativecommons.org");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Jonathan","Morales", "jmoralesa@ovh.net");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Marie","Morgan", "mmorganb@cloudflare.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Amanda","Nelson", "anelson13@indiatimes.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Lisa", "Olson", "lolsonr@telegraph.co.uk");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Alice", "Ortiz", "aortizw@histats.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Peter","Phillips", "pphillipss@1688.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Matthew","Porter", "mporter9@europa.eu");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Tammy", "Ray", "trayx@weather.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Mark","Richardson", "mrichardson1d@ihg.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Joan", "Roberts", "jroberts12@alibaba.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Kathleen", "Rose", "kroseg@pinterest.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Steve", "Sanders", "ssanders1b@wikispaces.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Shirley", "Scott", "sscottm@macromedia.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Lillian", "Stephens", "lstephens19@hugedomains.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Nicole", "Thompson", "nthompson3@admin.ch");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Marie", "Thompson", "mthompsonz@yelp.com");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Alan", "Vasquez", "avasquezo@miibeian.gov.cn");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Mildred", "Watkins", "mwatkins0@miibeian.gov.cn");
INSERT INTO `members`(`firstname`, `lastname`, `email`) VALUES ("Eugene", "Williams", "ewilliamsi@deliciousdays.com");
Beachten Sie, dass danach die id
-Werte andere sind, da es sich um einen AUTO INCREMENT
-Wert handelt.
Success
Wir haben unser Backend erfolgreich als REST-Server implementiert, der alle CRUD-Funktionalitäten umsetzt. Wir werden im nächsten Schritt das Frontend nun so gestalten, dass es auf die REST-API zugreift und das Backend für die Datenverwaltung verwendet.
Cross-Origin Resource Sharing (CORS)¶
Die Same Origin Policy (SOP) ist ein Sicherheitskonzept, das clientseitig Skriptsprachen (also z.B. JavaScript oder CSS) untersagt, Ressourcen aus verschiedenen Herkunften zu verwenden, also von verschiedenen Servern. Dadurch soll verhindert werden, dass fremde Skripte in die bestehende Client-Server-Kommunikation eingeschleust werden. Gleiche Herkunft (origin) bedeutet, dass das gleiche Protokoll (z.B. http
oder https
), von der gleichen Domain (z.B. localhost
oder htw-berlin
) sowie dem gleichen Port (z.B. 80
oder 4200
) verwendet werden. Es müssen alle drei Eigenschaften übereinstimmen.
Mit dem Aufkommen von Single Page Applications und dem darin benötigten AJAX kam jedoch der Bedarf auf, die SOP aufzuweichen. Es sollte möglich sein, dass z.B. JavaScript sowohl client-seitig das DOM ändert als auch einen Request an den Server (das Backend) sendet. Der Kompromiss, der dafür gefunden wurde, nennt sich Cross-Origin Resource Sharing (CORS). Damit ist es möglich, für einige oder alle Anfragen zu definieren, dass sie im Sinne der SOP trotzdem erlaub sein sollen.
Um CORS für Ihr Backend zu aktivieren, wechseln Sie im Terminal in Ihren backend
-Ordner und geben dort
npm install cors
ein. Öffnen Sie dann die server.js
und fügen Sie die hervorgehobenen Zeilen ein:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
Wenn Sie z.B. nur die get
-Anfrage teilen wollen, dann wählen Sie nicht app.use(cors());
, sondern
app.get("/", cors(), (req, res) => {
res.json({ message: "Hello FIW!" });
});
Mehr zum CORS-Paket von node.js bzw. express finden Sie hier.