Erstellen einer einfachen CRUD-App mit Node, Express und MongoDB

Ich habe endlich verstanden, wie man mit Node, Express und MongoDB arbeitet. Ich möchte ein umfassendes Tutorial schreiben, damit Sie nicht die gleichen Kopfschmerzen haben wie ich.

CRUD, Express und MongoDB

CRUD, Express und MongoDB sind große Worte für eine Person, die in ihrem Leben noch nie mit serverseitiger Programmierung in Berührung gekommen ist. Lassen Sie uns kurz vorstellen, was sie sind, bevor wir in das Tutorial eintauchen.

Express ist ein Framework zum Erstellen von Webanwendungen auf Basis von Node.js . Es vereinfacht den Servererstellungsprozess, der bereits in Node. Falls Sie sich fragen, ermöglicht Ihnen Node, JavaScript als serverseitige Sprache zu verwenden.

MongoDB ist eine Datenbank . Dies ist der Ort, an dem Sie Informationen für Ihre Websites (oder Anwendungen) speichern.

CRUD ist ein Akronym für Create, Read, Update und Delete . Es ist eine Reihe von Operationen, die wir von Servern ausführen lassen (POST , GET , PUT und DELETE Anfragen). Das macht jede Operation:

  • Erstellen (POST) - Etwas machen
  • Lesen (GET) - Holen Sie sich etwas
  • Aktualisieren (PUT) - Etwas ändern
  • Löschen (LÖSCHEN) - Etwas entfernen

POST , GET , PUT , und DELETE Anfragen lassen uns Rest-APIs erstellen.

Wenn wir CRUD, Express und MongoDB in einem einzigen Diagramm zusammenfassen, würde es so aussehen:

Sind CRUD, Express und MongoDB für Sie jetzt sinnvoller?

Groß. Weiter geht's.

Wir bauen gemeinsam eine einfache Anwendung

Lassen Sie uns eine einfache Anwendung erstellen, mit der Sie eine Liste mit Zitaten von Star Wars-Charakteren verfolgen können. So sieht es aus:

Probieren Sie kostenlos die Demo aus, bevor Sie mit diesem Tutorial fortfahren.

:::Hinweis
Dieser Artikel ist LANG! Denken Sie daran, den Quellcode abzurufen, indem Sie Ihren Namen und Ihre E-Mail-Adresse in diesem Formular hinterlassen . Ich schicke Ihnen diesen Artikel auch als PDF, damit Sie ihn in Ruhe lesen können.
:::

Übrigens werde ich mich nicht auf die Stile konzentrieren, da wir uns in diesem Tutorial auf das Erlernen von Crud, Express und MongoDB konzentrieren.

Voraussetzungen

Sie benötigen zwei Dinge, um mit diesem Tutorial zu beginnen:

  1. Sie haben keine Angst davor, Befehle in eine Befehlszeile einzugeben. Wenn Sie Angst haben, verwenden Sie diesen Artikel, um Ihre Angst zu überwinden.
  2. Node muss installiert sein.

Um zu überprüfen, ob Sie Node installiert haben, öffnen Sie Ihre Befehlszeile und führen Sie den folgenden Code aus:

$ node -v

Sie sollten eine Versionsnummer erhalten, wenn Sie Node installiert haben. Wenn Sie dies nicht tun, können Sie Node installieren, indem Sie entweder das Installationsprogramm von der Node-Website herunterladen oder es über Paketmanager wie Homebrew (Mac) und Chocolatey (Windows) herunterladen.

Erste Schritte

Erstellen Sie zunächst einen Ordner für dieses Projekt. Fühlen Sie sich frei, es zu nennen, wie Sie wollen. Nachdem Sie den Ordner erstellt haben, navigieren Sie mit dem Terminal hinein und führen Sie npm init aus .

npm init erstellt einen package.json Datei, die Ihnen hilft, Abhängigkeiten zu verwalten (die wir installieren werden, während wir das Tutorial durchgehen).

$ npm init

Drücken Sie einfach die Eingabetaste durch alles, was angezeigt wird. Ich werde über die sprechen, die Sie wissen müssen, während wir weitermachen.

Node zum ersten Mal in deinem Leben ausführen

Der einfachste Weg, den Knoten zu verwenden, besteht darin, node auszuführen Befehl und geben Sie einen Pfad zu einer Datei an. Lassen Sie uns eine Datei namens server.js erstellen Knoten mit auszuführen.

touch server.js

Als nächstes setzen Sie hier einen console.log Anweisung in server.js . Dadurch wissen wir, ob Node ordnungsgemäß ausgeführt wird.

// server.js
console.log("May Node be with you");

Führen Sie nun node server.js aus in Ihrer Befehlszeile und Sie sollten Folgendes sehen:

Groß. Knoten funktioniert. Der nächste Schritt besteht darin, die Verwendung von Express zu lernen.

Express verwenden

Zuerst müssen wir Express installieren. Wir können dies tun, indem wir npm install ausführen Befehl. (npm wird mit Node installiert, weshalb Sie Befehle wie npm init verwenden und npm install ).

Führen Sie npm install express --save aus Befehl in Ihrer Befehlszeile.

:::Hinweis
Die --save Flag speichert express als dependency in package.json . Es ist wichtig, diese Abhängigkeiten zu kennen, da npm kann Abhängigkeiten mit einem anderen npm install abrufen Befehl, wenn Sie ihn später brauchen.
:::

npm install express --save

Als nächstes verwenden wir express in server.js indem Sie es verlangen.

const express = require("express");
const app = express();

Wir müssen einen Server erstellen, mit dem sich Browser verbinden können. Wir tun dies, indem wir den listen des Express verwenden Methode.

app.listen(3000, function () {
  console.log("listening on 3000");
});

Führen Sie nun node server.js aus und navigieren Sie zu localhost:3000 auf Ihrem Browser. Sie sollten eine Nachricht mit dem Inhalt cannot get / sehen .

Das ist ein gutes Zeichen. Das bedeutet, dass wir jetzt über den Browser mit unserem Express-Server kommunizieren können . Hier beginnen wir mit CRUD-Operationen.

CRUD - LESEN

Browser führen das READ durch Betrieb, wenn Sie eine Website besuchen. Unter der Haube senden sie ein GET Anfrage an den Server, um diesen READ-Vorgang auszuführen.

Sie sehen cannot get / weil unser Server nichts an den Browser zurückgesendet hat.

In Express handhaben wir ein GET Anfrage mit dem get Methode:

app.get(endpoint, callback);

endpoint ist der angeforderte Endpunkt. Es ist der Wert, der nach Ihrem Domainnamen kommt. Hier sind einige Beispiele:

  • Wenn Sie localhost:3000 besuchen , besuchen Sie eigentlich localhost:3000/ . In diesem Fall forderten Browser / an .
  • Sie lesen diesen Artikel auf https://zellwk.com/blog/crud-express-mongodb/ . Der Domänenname ist zellwk.com . Der angeforderte Endpunkt ist alles, was nach zellwk.com kommt (das ist /blog/crud-express-mongodb ).

callback teilt dem Server mit, was zu tun ist, wenn der angeforderte Endpunkt mit dem angegebenen Endpunkt übereinstimmt. Es braucht zwei Argumente:A request Objekt und ein response Objekt.

// We normally abbreviate `request` to `req` and `response` to `res`.
app.get("/", function (req, res) {
  // do something here
});

Lassen Sie uns zunächst Hello World schreiben zurück zum Browser. Dazu verwenden wir einen send Methode, die mit response geliefert wird Objekt:

app.get("/", function (req, res) {
  res.send("Hello World");
});

Ich beginne mit dem Schreiben in ES6-Code und zeige Ihnen dabei auch, wie Sie in ES6 konvertieren. Zunächst einmal ersetze ich function() mit einer ES6-Pfeilfunktion. Der folgende Code ist derselbe wie der obige Code:

app.get("/", (req, res) => {
  res.send("Hello World");
});

Starten Sie jetzt Ihren Server neu, indem Sie Folgendes tun:

  1. Halten Sie den aktuellen Server an, indem Sie CTRL + C drücken in der Kommandozeile.
  2. Führen Sie node server.js aus wieder.

Navigieren Sie dann zu localhost:3000 auf Ihrem Browser. Sie sollten eine Zeichenfolge mit der Aufschrift "Hello World" sehen können.

Großartig.

Als Nächstes ändern wir server.js also servieren wir einen index.html Seite zurück zum Browser. Dazu verwenden wir den sendFile Methode, die von res bereitgestellt wird Objekt.

app.get("/", (req, res) => {
  res.sendFile(__dirname + "/index.html");
  // Note: __dirname is directory current directory you're in. Try logging it and see what you get!
  // Mine was '/Users/zellwk/Projects/demo-repos/crud-express-mongo' for this app.
});

Im sendFile Methode oben haben wir Express angewiesen, einen index.html zuzustellen Datei, die sich im Stammverzeichnis Ihres Projektordners befindet. Wir haben diese Datei noch nicht. Machen wir es jetzt.

touch index.html

Lassen Sie uns etwas Text in unseren index.html einfügen Datei auch:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>MY APP</title>
  </head>
  <body>
    <h1>May Node and Express be with you.</h1>
  </body>
</html>

Starten Sie Ihren Server neu und aktualisieren Sie Ihren Browser. Sie sollten jetzt Ihre HTML-Datei sehen können.

So verarbeitet Express ein GET Anfrage (LESEN Betrieb) auf den Punkt gebracht.

An diesem Punkt haben Sie wahrscheinlich erkannt, dass Sie Ihren Server neu starten müssen, wenn Sie eine Änderung an server.js vornehmen . Dieser Prozess ist unglaublich mühsam, also machen wir einen kurzen Umweg und optimieren ihn mit einem Tool namens nodemon.

Geben Sie Nodemon ein

Nodemon startet den Server automatisch neu wenn Sie eine Datei speichern, die von server.js verwendet wird . Wir können Nodemon mit dem folgenden Befehl installieren:

$ npm install nodemon --save-dev

:::Hinweis
Wir verwenden einen --save-dev Markieren Sie hier, weil wir Nodemon nur verwenden, wenn wir Sachen entwickeln. Wir werden Nodemon nicht auf einem tatsächlichen Server verwenden. --save-dev hier fügt Nodeman als devDependency hinzu im package.json Datei.
:::

Nodemod verhält sich wie Node. Sie können also nodemon server.js ausführen und Sie würden erwarten, dasselbe zu sehen. Leider funktioniert dies nur, wenn Sie nodemon global mit dem -g installiert haben Flagge (und das haben wir nicht getan).

Wir haben andere Möglichkeiten, Nodemon auszuführen. Beispielsweise können Sie Nodemon direkt aus dem node_modules ausführen Mappe. Das ist super unweildy, aber es funktioniert:

./node_modules/.bin/nodemon server.js

Wir können die Dinge einfacher machen, indem wir script hinzufügen Geben Sie package.json ein Datei. Dadurch können wir nodemon server.js ausführen ohne ./node_modules... Präambel.

{
  // ...
  "scripts": {
    "dev": "nodemon server.js"
  }
  // ...
}

Jetzt können Sie npm run dev ausführen um nodemon server.js auszulösen .

Zurück zum Hauptthema. Wir werden das CREATE abdecken nächster Vorgang.

CRUD - ERSTELLEN

Browser können nur ein CREATE ausführen Vorgang, wenn sie POST senden Anfrage an den Server. Diese POST Anfrage kann durch JavaScript oder durch einen <form> ausgelöst werden Element.

Lassen Sie uns herausfinden, wie man einen <form> verwendet Element, um vorerst neue Einträge für diese Star Wars-Angebotsanwendung zu erstellen. Wir werden später untersuchen, wie Anfragen über JavaScript gesendet werden.

Zum Senden einer POST-Anforderung über einen <form> müssen Sie den <form> hinzufügen -Element zu Ihrem index.html Datei.

Für dieses Formularelement benötigen Sie drei Dinge:

  1. Ein action Attribut
  2. A method Attribut
  3. name Attribute auf jedem <input> Elemente innerhalb des Formulars
<form action="/quotes" method="POST">
  <input type="text" placeholder="name" name="name" />
  <input type="text" placeholder="quote" name="quote" />
  <button type="submit">Submit</button>
</form>

Die method teilt dem Browser mit, welche Art von Anfrage gesendet werden soll. In diesem Fall verwenden wir POST weil wir einen POST senden Anfrage.

Der action -Attribut teilt dem Browser mit, wohin der POST gesendet werden soll Anfrage. In diesem Fall senden wir den POST Anfrage an /quotes .

Wir können mit diesem POST umgehen Anfrage mit einem post Methode in server.js . Die path Pfad sollte der Wert sein, den Sie in action eingegeben haben Attribut.

app.post("/quotes", (req, res) => {
  console.log("Hellooooooooooooooooo!");
});

Starten Sie Ihren Server neu (hoffentlich haben Sie Nodemon so eingerichtet, dass er automatisch neu startet) und aktualisieren Sie Ihren Browser. Geben Sie dann etwas in <form> ein Element und senden Sie das Formular ab. Sehen Sie sich als Nächstes Ihre Befehlszeile an. Sie sollten Hellooooooooooooooooo! sehen in Ihrer Befehlszeile.

Großartig, wir wissen, dass Express das Formular gerade für uns bearbeitet. Die nächste Frage ist, wie bekommen wir die Eingabewerte mit Express?

Es stellt sich heraus, dass Express das Lesen von Daten vom <form> nicht handhabt Element für sich. Wir müssen ein weiteres Paket namens body-parser hinzufügen, um diese Funktionalität zu erhalten.

npm install body-parser --save

Body-Parser ist eine Middleware . Sie helfen beim Aufräumen im request Objekt, bevor wir sie verwenden. Express lässt uns Middleware mit dem use verwenden Methode.

const express = require("express");
const bodyParser = require("body-parser");
const app = express();

// Make sure you place body-parser before your CRUD handlers!
app.use(bodyParser.urlencoded({ extended: true }));

// All your handlers here...
app.get("/", (req, res) => {
  /*...*/
});
app.post("/quotes", (req, res) => {
  /*...*/
});

Die urlencoded Methode innerhalb des Body-Parsers weist den Body-Parser an, Daten aus <form> zu extrahieren -Element und fügen Sie sie dem body hinzu -Eigenschaft in request Objekt.

Sie sollten Werte von <form> sehen können Element innerhalb von req.body jetzt. Versuchen Sie es mit console.log und sehen, was es ist!

app.post("/quotes", (req, res) => {
  console.log(req.body);
});

Sie sollten ein Objekt ähnlich dem Folgenden sehen:

Hmm.

Meister Yoda hat gesprochen! Stellen wir sicher, dass wir uns an Yodas Worte erinnern. Es ist wichtig. Wir möchten es beim nächsten Laden unserer Indexseite abrufen können.

Geben Sie die Datenbank MongoDB ein.

MongoDB

MongoDB ist eine Datenbank. Wir können Informationen in dieser Datenbank speichern, um uns an Yodas Worte zu erinnern. Anschließend können wir diese Informationen abrufen und Personen anzeigen, die unsere App aufrufen.

:::Hinweis
Normalerweise verwende ich Mongoose (ein Framework für MongoDB), wenn ich MongoDB verwende. In diesem Artikel werde ich Ihnen beibringen, wie Sie die grundlegende MongoDB verwenden. Wenn Sie Mongoose lernen möchten, sollten Sie meinen Artikel über Mongoose lesen.
:::

Zuerst müssen wir MongoDB über npm installieren.

npm install mongodb --save

Nach der Installation können wir uns über MongoClient mit MongoDB verbinden 's connect-Methode, wie im folgenden Code gezeigt:

const MongoClient = require("mongodb").MongoClient;
MongoClient.connect("mongodb-connection-string", (err, client) => {
  // ... do something here
});

Der nächste Teil besteht darin, den richtigen Link zu unserer Datenbank zu erhalten. Die meisten Menschen speichern ihre Datenbanken in Cloud-Diensten wie MongoDB Atlas. Das werden wir auch tun. (Es ist kostenlos).

:::Hinweis
Sie können auch eine Datenbank für Entwicklungsarbeiten auf Ihrem Computer erstellen. Lesen Sie „How to setup a local MongoDB Connection“ für Anweisungen.
:::

Einrichten von MongoDB Atlas

Leg los und erstelle ein Konto bei MongoDB Atlas. Sobald Sie fertig sind, müssen Sie eine "Organisation" erstellen. Es ist so etwas wie ein Firmenname. Sie können es beliebig benennen. (Sie können es später ändern).

Sie müssen auch einen Cloud-Dienst auswählen. Fahren Sie in diesem Fall mit MongoDB Atlas fort.

Als Nächstes müssen Sie Berechtigungen für Benutzer festlegen. MongoDB Atlas füllt automatisch Ihre aktuelle E-Mail-Adresse als Benutzer aus. Fahren Sie also einfach mit dem nächsten Schritt fort.

Sie sollten am Ende einen Bildschirm sehen, der so aussieht:

Als nächstes müssen Sie eine Datenbank in MongoDB Atlas erstellen. Dazu gibt es mehrere Schritte.

Zuerst müssen Sie ein neues Projekt erstellen. Sie können dies tun, indem Sie im oberen linken Menü unter "Kontext" gehen. Klicken Sie auf das Dropdown-Menü. Wählen Sie dann Neues Projekt.

Als nächstes müssen Sie Ihr Projekt benennen. Nennen Sie es wie Sie wollen. Ich nenne dies star-wars .

Dann müssen Sie Mitglieder hinzufügen. Auch hier sind Sie bereits hinzugefügt, also fahren Sie fort und klicken Sie auf "Projekt erstellen", um fortzufahren.

Am Ende sollte ein Bildschirm mit der Meldung „Create a Cluster“ angezeigt werden.

Klicken Sie auf „Cluster erstellen“. Sie sollten diesen Bildschirm sehen:

Wählen Sie den freien Cluster (linke Option) und fahren Sie fort. Sie sollten jetzt einen Bildschirm zum Konfigurieren eines Clusters sehen. Runterscrollen. Stellen Sie sicher, dass Sie diese beiden Dinge sehen:

  1. Clusterebene ist M0 Sandbox
  2. Die monatliche Schätzung ist KOSTENLOS

Klicken Sie als Nächstes auf Cluster erstellen. Sie sollten "Ihr Cluster wird erstellt" sehen.

Sie müssen ca. 5 Minuten auf die Cluster-Erstellung warten. Wenn der Cluster bereit ist, sehen Sie Folgendes:

Jetzt müssen wir unsere Star Wars-App mit diesem Cluster verbinden.

Verbindung mit MongoDB Atlas

Klicken Sie auf die Schaltfläche Verbinden.

Ein Modal sollte erscheinen.

Sie müssen Ihre IP-Adresse auf die Whitelist setzen, bevor Sie eine Verbindung zu Ihrem Cluster herstellen können. Dies ist eine in MongoDB Atlas integrierte Sicherheitsfunktion. Fahren Sie fort und klicken Sie auf "Ihre aktuelle IP-Adresse hinzufügen".

Als nächstes müssen Sie einen MongoDB-Benutzer erstellen. Dieser Benutzername und dieses Passwort unterscheiden sich von denen, mit denen Sie sich bei MongoDB Atlas angemeldet haben. Dieser Benutzername und dieses Passwort werden NUR für die Datenbank verwendet.

Stellen Sie sicher, dass Sie sich MongoDB-Benutzer und -Passwort merken. Wir verwenden es, um eine Verbindung zur Datenbank herzustellen.

Klicken Sie anschließend auf Wählen Sie Ihre Verbindungsmethode. Wählen Sie „Mit Ihrer Anwendung verbinden“ und kopieren Sie die Verbindungszeichenfolge.

Die Verbindungszeichenfolge sollte in etwa so aussehen:

"mongodb+srv://<username>:<password>@<clustername>-rmp3c.mongodb.net/test?retryWrites=true&w=majority";

Sie müssen hier 2 Dinge ersetzen:

  1. Ersetzen Sie <username> mit Ihrem Datenbank-Benutzernamen
  2. Ersetzen Sie <password> mit dem Passwort des Datenbankbenutzers

:::Hinweis
Die test in der Verbindungszeichenfolge zeigt auf einen test Datenbank. Sie müssten test ersetzen mit dem Namen Ihrer Datenbank, wenn Sie Mongoose verwenden. Sie können es auf test belassen wenn Sie MongoClient wie in diesem Tutorial verwenden.
:::

Fügen Sie diese Verbindungszeichenfolge in MongoClient.connect ein .

MongoClient.connect(connectionString, (err, client) => {
  // ... do something here
}))

Wir wissen, dass wir uns mit der Datenbank verbunden haben, wenn keine Fehler vorliegen. Lassen Sie uns console.log erstellen Anweisung mit der Aufschrift "Connected to database". Dies hilft uns zu wissen, dass wir eine Verbindung zur Datenbank hergestellt haben, wenn wir den Server neu starten.

MongoClient.connect(connectionString, (err, client) => {
  if (err) return console.error(err);
  console.log("Connected to Database");
});

Sie sollten so etwas sehen:

Sie können die Verfallswarnung entfernen, indem Sie die Option zu MongoClient.connect hinzufügen

MongoClient.connect(
  connectionString,
  {
    useUnifiedTopology: true,
  },
  (err, client) => {
    if (err) return console.error(err);
    console.log("Connected to Database");
  }
);

MongoDB unterstützt Versprechungen. Wenn Sie Promises anstelle von Callbacks verwenden möchten, können Sie MongoClient.connect schreiben so was. Es verhält sich genau wie der obige Code.

MongoClient.connect(connectionString, { useUnifiedTopology: true })
  .then((client) => {
    console.log("Connected to Database");
  })
  .catch((error) => console.error(error));

:::Hinweis
Lesen Sie diesen Artikel, wenn Sie mehr über Promises in JavaScript erfahren möchten.
:::

Ändern der Datenbank

Wir müssen die Datenbank von test ändern zu etwas anderem. Sie können es beliebig benennen. Ich habe den Namen meiner neuen Datenbank star-wars-quotes gewählt weil es mir hilft, mich daran zu erinnern, was ich baue.

MongoClient.connect(connectionString, { useUnifiedTopology: true }).then(
  (client) => {
    console.log("Connected to Database");
    const db = client.db("star-wars-quotes");
  }
);

MongoDB und Server

Wir brauchen den db Variable von der Verbindung zu, um auf MongoDB zuzugreifen. Das bedeutet, dass wir unsere Express-Request-Handler in then von MongoClient einfügen müssen Anruf.

MongoClient.connect(/* ... */)
  .then((client) => {
    // ...
    const db = client.db("star-wars-quotes");
    app.use(/* ... */);
    app.get(/* ... */);
    app.post(/* ... */);
    app.listen(/* ... */);
  })
  .catch(console.error);

Wir können jetzt endlich Yodas Zitat in der Datenbank speichern!

CRUD - ERSTELLEN (Fortsetzung)

Wir müssen einen collection erstellen bevor wir Artikel in einer Datenbank speichern können. Hier ist eine einfache Analogie, die Ihnen hilft, die Begriffe in MongoDB zu klären:

  • Stellen Sie sich vor, eine Datenbank ist ein Raum.
  • Ein Raum enthält Kisten (collections ).

Wie Datenbanken können Sie Sammlungen beliebig benennen. Lassen Sie uns in diesem Fall Anführungszeichen in quotes speichern Sammlung. Wir verwenden db.collection Sammlung angeben.

MongoClient.connect(/* ... */).then((client) => {
  // ...
  const db = client.db("star-wars-quotes");
  const quotesCollection = db.collection("quotes");

  // ...
});

Wir können den insertOne verwenden -Methode zum Hinzufügen von Elementen zu einer MongoDB-Sammlung.

app.post("/quotes", (req, res) => {
  quotesCollection
    .insertOne(req.body)
    .then((result) => {
      console.log(result);
    })
    .catch((error) => console.error(error));
});

Versuchen Sie, <form> einzureichen aus dem Browser. Sie sollten ein großes, unheimlich aussehendes result sehen im Terminal.

Wenn Sie das sehen, herzlichen Glückwunsch! Sie haben das Angebot erfolgreich zur Datenbank hinzugefügt.

Sie können die Elemente in der Datenbank überprüfen, indem Sie in MongoDB Atlas zu „Sammlungen“ gehen.

Sie sollten ein Dokument in Ihrer Datenbank sehen. (Jeder Datenbankeintrag wird als Dokument bezeichnet).

Wenn Sie zum Browser zurückkehren, sehen Sie, dass er immer noch versucht, etwas zu laden.

Dies geschieht, weil der Browser etwas vom Server zurückerwartet.

In diesem Fall müssen wir die Browserinformationen nicht senden. Lassen Sie uns den Browser bitten, zurück zu / umzuleiten stattdessen. Wir machen das mit res.redirect .

app.post("/quotes", (req, res) => {
  quotesCollection
    .insertOne(req.body)
    .then((result) => {
      res.redirect("/");
    })
    .catch((error) => console.error(error));
});

Juhu!

Da wir einige Zitate in der Sammlung haben, zeigen wir sie unserem Benutzer, wenn sie auf der Seite landen!

Anführungszeichen für Benutzer anzeigen (READ-Operation)

Wir müssen zwei Dinge tun, um unseren Benutzern Zitate aus MongoDB Atlas anzuzeigen.

  1. Holen Sie Angebote von MongoDB Atlas ein.
  2. Rendering der Zitate in HTML mit einer Template-Engine

Gehen wir einen Schritt nach dem anderen vor.

Angebote von MongoDB abrufen

Wir können Kurse abrufen, die wir in MongoDB mit dem find gespeichert haben Methode. Diese Methode von mLab mit dem find Methode, die in collection verfügbar ist Methode.

app.get("/", (req, res) => {
  const cursor = db.collection("quotes").find();
  console.log(cursor);
  // ...
});

Der find Methode gibt einen cursor zurück was keinen Sinn ergibt, wenn Sie versuchen, es zu protokollieren.

Aber dieses cursor Objekt enthält alle Zitate aus unserer Datenbank! Es hat eine Reihe von Methoden, mit denen wir unsere Daten abrufen können. Beispielsweise können wir toArray verwenden um die Daten in ein Array umzuwandeln.

app.get("/", (req, res) => {
  db.collection("quotes")
    .find()
    .toArray()
    .then((results) => {
      console.log(results);
    })
    .catch((error) => console.error(error));
  // ...
});

Groß! Wir sehen die Zitate, die wir hinzugefügt haben! (Sie sehen so viele der gleichen Zitate, weil ich sie alle hinzugefügt habe, als ich dieses Tutorial geschrieben habe 😆).

Als nächstes wollen wir einen HTML-Code generieren, der alle unsere Zitate enthält.

Rendern des HTML

index.html können wir nicht anbieten Datei und erwarten, dass Anführungszeichen auf magische Weise erscheinen, da es keine Möglichkeit gibt, dynamischen Inhalt zu einer HTML-Datei hinzuzufügen.

Was wir stattdessen tun können, ist, eine Template-Engine zu verwenden, um den HTML-Code zu generieren. Beliebte Template-Engines sind Pug, Embedded JavaScript und Nunjucks.

:::Hinweis
Ich habe in einem separaten Beitrag ausführlich über das Wie und Warum von Template-Engines geschrieben. Vielleicht möchten Sie es ausprobieren, wenn Sie keine Ahnung haben, was Vorlagen-Engines sind.

Ich verwende Nunjucks als bevorzugte Template-Engine. Schauen Sie sich den Beitrag an, um herauszufinden, warum.
:::

Für dieses Tutorial verwenden wir Embedded JavaScript (EJS) als unsere Vorlagen-Engine, da es am einfachsten ist, damit zu beginnen. Es wird Ihnen von Anfang an vertraut vorkommen, da Sie HTML und JavaScript schreiben werden.

EJS verwenden

Zuerst müssen wir EJS installieren.

npm install ejs --save

Als nächstes müssen wir view engine einstellen bis ejs . Dies teilt Express mit, dass wir EJS als Vorlagen-Engine verwenden. Sie müssen es möglicherweise vor jedem app.use platzieren , app.get oder app.post Methoden.

app.set("view engine", "ejs");

// Middlewares and other routes here...

Wir können jetzt HTML generieren, das die Anführungszeichen enthält . Dieser Vorgang wird als Rendering bezeichnet das HTML.

Wir verwenden den render Methode, die in response von Express integriert ist . Es muss der folgenden Syntax folgen:

res.render(view, locals);
  • view ist der Name der Datei, die wir rendern. Diese Datei muss innerhalb eines views platziert werden Ordner.
  • locals sind die in die Datei übergebenen Daten.

Lassen Sie uns eine Ansicht erstellen. Wir machen einen index.ejs Datei im Views-Ordner.

mkdir views
touch views/index.ejs

Wir werden alles ab index.html kopieren/einfügen in index.ejs .

<!-- index.ejs -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Star Wars Quote App</title>
  </head>

  <body>
    <h1>May Node and Express be with you.</h1>

    <form action="/quotes" method="POST">
      <input type="text" placeholder="name" name="name" />
      <input type="text" placeholder="quote" name="quote" />
      <button type="submit">Submit</button>
    </form>
  </body>
</html>

Als Nächstes verwenden wir res.render um diesen index.ejs zu rendern Datei.

app.get("/", (req, res) => {
  db.collection("quotes").find().toArray().then(/* ... */).catch(/* ... */);
  res.render("index.ejs", {});
});

Wenn Sie die Seite aktualisieren, sollten Sie immer noch dasselbe sehen. Nichts soll sich ändern, nichts soll kaputtgehen.

Setzen wir die Anführungszeichen in index.ejs . Dazu müssen wir die Anführungszeichen in render übergeben Methode.

app.get("/", (req, res) => {
  db.collection("quotes")
    .find()
    .toArray()
    .then((results) => {
      res.render("index.ejs", { quotes: results });
    })
    .catch(/* ... */);
});

In index.ejs , können wir Platzvariablen zwischen <%= verwenden und %> Stichworte. Versuchen wir es mit quotes in den HTML-Code:

<!-- In index.ejs -->
<body>
  <h1>...</h1>
  <form>...</form>
  <%= quotes %>
</body>

Sie sollten Folgendes sehen:

Wir sehen viele [object Object] weil jedes Zitat innerhalb von results ist ein JavaScript-Objekt. ejs kann dieses Objekt nicht automatisch in HTML konvertieren.

Wir müssen die Anführungszeichen durchlaufen. Wir können dies mit einem for tun Schleife. In EJS schreiben wir eine for-Schleife, so wie wir JavaScript for schreiben Schleife. Der einzige Unterschied besteht darin, dass wir for einfügen müssen Schleifenanweisungen zwischen <% und %> .

<h2>Quotes</h2>

<ul class="quotes">
  <!-- Loop through quotes -->
  <% for(var i = 0; i < quotes.length; i++) {%>
  <li class="quote">
    <!-- Output name from the iterated quote object -->
    <span><%= quotes[i].name %></span>:
    <!-- Output quote from the iterated quote object -->
    <span><%= quotes[i].quote %></span>
  </li>
  <% } %>
</ul>

CRUD - UPDATE

Wir verwenden das UPDATE Betrieb, wenn wir etwas verändern wollen. Es kann mit einem PUT ausgelöst werden Anfrage. Wie POST , PUT kann entweder durch JavaScript oder durch einen <form> ausgelöst werden Element.

Lassen Sie uns die Dinge ändern und JavaScript verwenden, da Sie bereits wissen, wie man <form> verwendet Elemente.

Für diesen Aktualisierungsvorgang erstellen wir eine Schaltfläche, die das erste Zitat von Yoda durch etwas ersetzt, das von Darth Vadar geschrieben wurde.

Dazu müssen wir einen button hinzufügen in den index.ejs Datei:

<div>
  <h2>Darth Vadar invades!</h2>
  <p>
    Replace first Yoda's quote with a quote written by Darth Vadar
  </p>
  <button id="update-button">Replace Yoda's quote</button>
</div>

Wir werden auch eine externe JavaScript-Datei erstellen, um einen PUT auszuführen Anfrage. Gemäß den Express-Konventionen wird dieses JavaScript in einem Ordner mit dem Namen public aufbewahrt

$ mkdir public
$ touch public/main.js

Dann müssen wir Express sagen, dass es public machen soll Ordner, der für die Öffentlichkeit zugänglich ist, indem eine integrierte Middleware namens express.static verwendet wird

app.use(express.static("public"));

Wir können jetzt den main.js hinzufügen Datei in index.ejs Datei:

<body>
  <!-- ... -->
  <script src="/main.js"></script>
</body>

Wir senden einen PUT Anfrage, wenn auf die Schaltfläche geklickt wird. Das bedeutet, dass wir uns ein click anhören müssen Veranstaltung.

Als Nächstes senden wir den PUT Abfrage beim Klick auf die Schaltfläche:

// main.js
const update = document.querySelector("#update-button");

update.addEventListener("click", (_) => {
  // Send PUT Request here
});

Senden einer PUT-Anfrage

Der einfachste Weg, einen PUT auszulösen Anforderung in modernen Browsern ist die Verwendung der Fetch-API.

Fetch hat die folgende Syntax:

fetch(endpoint, options);

Nehmen wir in diesem Fall an, wir möchten die Anfrage an /quotes senden . Wir setzen endpoint bis /quotes .

update.addEventListener("click", (_) => {
  fetch("/quotes", {
    /* ... */
  });
});

Wir müssen einen PUT senden diesmal anfordern. Wir können dies tun, indem wir die Methode von Fetch auf put setzen .

update.addEventListener("click", (_) => {
  fetch("/quotes", {
    method: "put",
  });
});

Moderne Anwendungen senden JSON-Daten an Server. Sie erhalten auch JSON-Daten zurück an Server. JSON steht für JavaScript Object Notation. Sie sind wie JavaScript-Objekte, aber jede Eigenschaft und jeder Wert wird zwischen zwei Anführungszeichen geschrieben.

Hier ist ein Beispiel für JavaScript-Daten:

const data = {
  name: "Darth Vadar",
  quote: "I find your lack of faith disturbing.",
};

Und wie sein JSON-Gegenstück aussieht. (Beachten Sie, wie alles zwischen zwei " ).

{
  "name": "Darth Vadar",
  "quote": "I find your lack of faith disturbing."
}

Wir müssen dem Server mitteilen, dass wir JSON-Daten senden, indem wir den Content-Type setzen Kopfzeilen zu application/json .

update.addEventListener("click", (_) => {
  fetch("/quotes", {
    method: "put",
    headers: { "Content-Type": "application/json" },
  });
});

Als nächstes müssen wir die von uns gesendeten Daten in JSON konvertieren. Wir können dies mit JSON.stringify tun . Diese Daten werden über den body übergeben Eigentum.

update.addEventListener("click", (_) => {
  fetch("/quotes", {
    method: "put",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      name: "Darth Vadar",
      quote: "I find your lack of faith disturbing.",
    }),
  });
});

Annahme der PUT-Anfrage

Unser Server akzeptiert noch keine JSON-Daten. Wir können ihm beibringen, JSON zu lesen, indem wir den body-parser hinzufügen ist json Middleware.

app.use(bodyParser.json());

Als nächstes können wir mit PUT umgehen Anfrage mit einem put Methode. Sie sollten die Werte sehen können, die wir von der Abrufanforderung senden.

app.put("/quotes", (req, res) => {
  console.log(req.body);
});

Der nächste Schritt besteht darin, das erste Zitat von Yoda in dieses Zitat von Darth Vadar zu ändern.

Änderung von Yodas Zitat

MongoDB-Sammlungen enthalten eine Methode namens findOneAndUpdate . Mit dieser Methode können wir ein Element in der Datenbank finden und ändern. Es hat die folgende Syntax:

quotesCollection
  .findOneAndUpdate(query, update, options)
  .then((result) => {
    /* ... */
  })
  .catch((error) => console.error(error));

query Lassen Sie uns die Sammlung mit Schlüssel-Wert-Paaren filtern. Wenn wir Zitate auf die von Yoda geschriebenen filtern möchten, können wir { name: 'Yoda' } einstellen als Abfrage.

quotesCollection
  .findOneAndUpdate({ name: "Yoda" }, update, options)
  .then((result) => {
    /* ... */
  })
  .catch((error) => console.error(error));

update , teilt MongoDB mit, was geändert werden soll. Es verwendet die Update-Operatoren von MongoDB wie $set , $inc und $push .

Wir verwenden den $set Operator, da wir Yodas Zitate in Darth Vadars Zitate ändern:

quotesCollection
  .findOneAndUpdate(
    { name: "Yoda" },
    {
      $set: {
        name: req.body.name,
        quote: req.body.quote,
      },
    },
    options
  )
  .then((result) => {
    /* ... */
  })
  .catch((error) => console.error(error));

options weist MongoDB an, zusätzliche Optionen für diese Aktualisierungsanforderung zu definieren.

In diesem Fall ist es möglich, dass keine Yoda-Zitate in der Datenbank vorhanden sind. Wir können MongoDB zwingen, ein neues Darth Vadar-Zitat zu erstellen, wenn keine Yoda-Zitate vorhanden sind. Dazu setzen wir upsert bis true . upsert bedeutet:Fügen Sie ein Dokument ein, wenn keine Dokumente aktualisiert werden können.

quotesCollection
  .findOneAndUpdate(
    { name: "Yoda" },
    {
      $set: {
        name: req.body.name,
        quote: req.body.quote,
      },
    },
    {
      upsert: true,
    }
  )
  .then((result) => {
    /* ... */
  })
  .catch((error) => console.error(error));

Lassen Sie uns zum Schluss result protokollieren in die Kommandozeile.

app.put('/quotes', (req, res) => {
  quotesCollection.findOneAndUpdate(/* ... */)
    .then(result => {
      console.log(result)
     })
    .catch(error => console.error(error))
}

Versuchen Sie, im Browser auf die Schaltfläche „Erstes Yoda-Zitat ersetzen“ zu klicken. Sie sollten dieses Ergebnis in Ihrer Befehlszeile sehen. Dies besagt, dass wir eines von Yodas Zitaten geändert haben.

Wenn Sie den Browser aktualisieren, sollten Sie das Zitat von Darth Vadar als erstes Zitat sehen.

:::Hinweis
Macht den findOneAndUpdate sieht für dich kompliziert aus? Nun, es IST kompliziert. Aus diesem Grund verwende ich Mongoose anstelle von MongoDB. In diesem Artikel erfährst du mehr über Mongoose.
:::

Schließlich müssen wir auf das JavaScript antworten, das PUT gesendet hat Anfrage. In diesem Fall senden wir einfach den success Botschaft.

app.put('/quotes', (req, res) => {
  quotesCollection.findOneAndUpdate(/* ... */)
    .then(result => {
       res.json('Success')
     })
    .catch(error => console.error(error))
}

Als nächstes können wir die Antwort vom Server über einen then behandeln Objekt. (Wir tun dies, weil fetch gibt ein Versprechen zurück). Fetch unterscheidet sich jedoch geringfügig von den meisten Versprechungen. Sie müssen einen anderen then verwenden Objekt, um die Antwort vom Server zu erhalten.

Folgendes sollten Sie tun:

fetch({
  /* request */
})
  .then((res) => {
    if (res.ok) return res.json();
  })
  .then((response) => {
    console.log(response);
  });

Sie sollten einen Success sehen können Nachricht vom Server in der Konsole.

:::Hinweis
Ich habe einen Artikel über die Fetch-API geschrieben, falls Sie sich fragen, warum wir zwei then benötigen Anrufe. Lesen Sie es! Es wird helfen, Ihr Verständnis zu festigen.
:::

Wenn Sie an einer ausgefallenen Webanwendung arbeiten, können Sie JavaScript verwenden, um das DOM zu aktualisieren, sodass die Benutzer die neuen Änderungen sofort sehen.

Das Aktualisieren des DOM ist jedoch nicht Gegenstand dieses Artikels, daher aktualisieren wir nur den Browser, um die Änderungen zu sehen.

fetch({
  /* request */
})
  .then((res) => {
    if (res.ok) return res.json();
  })
  .then((response) => {
    window.location.reload(true);
  });

:::Hinweis
Wenn Sie lernen möchten, wie Sie JavaScript verwenden, um das DOM zu aktualisieren, empfehle ich Ihnen, meinen Kurs „JavaScript lernen“ zu durchlaufen. Ich bringe Ihnen sogar bei, wie Sie Ihre Benutzeroberfläche schnell und bissig machen! (Überprüfen Sie die Todolist-Komponente).
:::

Das war's für das UPDATE Betrieb! Fahren wir mit dem Löschen fort.

CRUD - LÖSCHEN

Das LÖSCHEN Der Vorgang kann durch ein DELETE ausgelöst werden Anfrage. Es ähnelt dem UPDATE Anfrage, also sollte dies einfach sein, wenn Sie verstehen, was wir oben getan haben.

For this, let's delete the first quote by Darth Vadar.

First, we need to add a delete button to index.ejs .

<div>
  <h2>Remove Darth Vadar!</h2>
  <p>
    Delete one Darth Vadar's quote. Does nothing if there are no more Darth
    Vadar's quote
  </p>
  <button id="delete-button">Delete Darth Vadar's quote</button>
</div>

Then, we'll trigger a DELETE request through Fetch when a user clicks the delete button.

const deleteButton = document.querySelector("#delete-button");

deleteButton.addEventListener("click", (_) => {
  fetch("/quotes", {
    method: "delete",
  });
});

Since we're deleting a quote by Darth Vadar, we only need to send Darth Vadar's name to the server.

deleteButton.addEventListener('click', _ => {
  fetch(/* ... */, {
    method: 'delete',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      name: 'Darth Vadar'
    })
  })
    .then(res => {
      if (res.ok) return res.json()
    })
    .then(data => {
      window.location.reload()
    })
})

We can then handle the event on our server side with the delete Methode:

app.delete("/quotes", (req, res) => {
  // Handle delete event here
});

Deleting a document from MongoDB

MongoDB Collections has a method called deleteOne . It lets us remove a document from the database. It takes in two parameters:query and options .

quotesCollection
  .remove(query, options)
  .then((result) => {
    /* ... */
  })
  .catch((error) => console.error(error));

query works like query in findOneAndUpdate . It lets us filter the collection to the entries we're searching for. In this case, we can set name to Darth Vadar.

quotesCollection
  .remove({ name: "Darth Vadar" }, options)
  .then((result) => {
    /* ... */
  })
  .catch((error) => console.error(error));

However, since we already pass the name Darth Vadar from Fetch, we don't need to hardcode it in Express anymore. We can simply use req.body.name .

app.delete("/quotes", (req, res) => {
  quotesCollection.remove({ name: req.body.name }, options);
});

In this case, we don't need to change any options, so we can omit options .

app.delete("/quotes", (req, res) => {
  quotesCollection.deleteOne({ name: req.body.name });
});

Then, we can send a response back to the JavaScript in the then Anruf.

app.delete("/quotes", (req, res) => {
  quotesCollection
    .deleteOne({ name: req.body.name })
    .then((result) => {
      res.json(`Deleted Darth Vadar's quote`);
    })
    .catch((error) => console.error(error));
});

Now, when you click the delete button, the browser will sends DELETE request through Fetch to our Express server. Then, the server responds by sending either an error or a message back.

What if there are no more Darth Vadar quotes?

If there are no more Darth Vadar quotes, result.deletedCount will be 0 . We can send a message that says tells the browser that there are no more Darth Vadar quotes to delete.

app.delete("/quotes", (req, res) => {
  quotesCollection
    .deleteOne(/* ... */)
    .then((result) => {
      if (result.deletedCount === 0) {
        return res.json("No quote to delete");
      }
      res.json(`Deleted Darth Vadar's quote`);
    })
    .catch((error) => console.error(error));
});

If the JavaScript receives a No quote to delete response, we can tell the user there's no Darth Vadar quote to delete.

To do this, let's add an element where we can tell users about this message.

<div id="message"></div>

If we receive No quote to delete , we can change the textContent of this .message div.

const messageDiv = document.querySelector("#message");

deleteButton.addEventListener("click", (_) => {
  fetch(/* ... */)
    .then(/* ... */)
    .then((response) => {
      if (response === "No quote to delete") {
        messageDiv.textContent = "No Darth Vadar quote to delete";
      } else {
        window.location.reload(true);
      }
    })
    .catch(/* ... */);
});

That's it for the DELETE operation!

Make it look better...

The final step is to make the app look a little better by sprinkling some styles!

Abschluss

We covered A LOT in this mega tutorial. Here's a list of things we've done together:

  1. Understood what Express, Node, and MongoDB are used for
  2. Understood CRUD
  3. Executed Create, Read, Update and Delete operations
  4. Created an Atlas account for MongoDB
  5. Save, read, update, and delete from MongoDB
  6. Display variable data with template engines

You have now learned all you need to know about creating simple applications with Node, Express, and MongoDB. Now, go forth and create more applications, young padawan. May the force be with you.

Grab the Source Code

You can grab the source code by leaving your name and email address in this form. I'll also send you this article in PDF so you can read it at your leisure.

Weiterführende Literatur

Here's some further readings if you're interested to continue with the Node, Express, MongoDB journey

  • Express articles - 3 useful Express middleware - Handling Express errors - JavaScript Async/await - Using Async/await in Express
  • MongoDB articles - Mongoose 101
  • Testing related articles - Endpoint testing with Jest and Supertest - Connecting Jest and Mongoose

Danke fürs Lesen. Dieser Artikel wurde ursprünglich auf meinem Blog veröffentlicht. Melden Sie sich für meinen Newsletter an, wenn Sie weitere Artikel wünschen, die Ihnen dabei helfen, ein besserer Frontend-Entwickler zu werden.