So integrieren Sie MongoDB in Ihre Node-Anwendung

Einführung

Während Sie mitNode.js arbeiten, entwickeln Sie möglicherweise ein Projekt, in dem Daten gespeichert und abgefragt werden. In diesem Fall müssen Sie eine Datenbanklösung auswählen, die für die Daten- und Abfragetypen Ihrer Anwendung sinnvoll ist.

In diesem Lernprogramm integrieren Sie eineMongoDB-Datenbank in eine vorhandene Knotenanwendung. NoSQL databases wie MongoDB können nützlich sein, wenn Ihre Datenanforderungen Skalierbarkeit und Flexibilität umfassen. MongoDB lässt sich auch gut in Node integrieren, da es so konzipiert ist, dass es asynchron mitJSON-Objekten arbeitet.

Um MongoDB in Ihr Projekt zu integrieren, verwenden SieObject Document Mapper (ODM)Mongoose, um Schemas und Modelle für Ihre Anwendungsdaten zu erstellen. Auf diese Weise können Sie Ihren Anwendungscode nach dem Architekturmuster vonmodel-view-controller (MVC)organisieren. Auf diese Weise können Sie die Logik, wie Ihre Anwendung Benutzereingaben verarbeitet, von der Struktur und Darstellung Ihrer Daten für den Benutzer trennen. Die Verwendung dieses Musters kann zukünftige Tests und Entwicklungen erleichtern, indem Bedenken in Ihre Codebasis aufgenommen werden.

Am Ende des Tutorials erhalten Sie eine funktionierende Anwendung für Haiinformationen, mit der ein Benutzer Eingaben zu seinen Lieblingshaien vornimmt und die Ergebnisse im Browser anzeigt:

Shark Output

Voraussetzungen

[[Schritt-1 - Erstellen eines Mongo-Benutzers]] == Schritt 1 - Erstellen eines Mongo-Benutzers

Bevor wir mit dem Anwendungscode arbeiten, erstellen wir einen Administrator, der Zugriff auf die Datenbank unserer Anwendung hat. Dieser Benutzer verfügt über Administratorrechte für jede Datenbank, wodurch Sie die Flexibilität haben, bei Bedarf zu wechseln und neue Datenbanken zu erstellen.

Überprüfen Sie zunächst, ob MongoDB auf Ihrem Server ausgeführt wird:

sudo systemctl status mongodb

Die folgende Ausgabe zeigt an, dass MongoDB ausgeführt wird:

Output● mongodb.service - An object/document-oriented database
   Loaded: loaded (/lib/systemd/system/mongodb.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2019-01-31 21:07:25 UTC; 21min ago
...

Öffnen Sie als Nächstes die Mongo-Shell, um Ihren Benutzer zu erstellen:

mongo

Dadurch gelangen Sie in eine Verwaltungsshell:

OutputMongoDB shell version v3.6.3
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.3
...
>

Beim Öffnen der Shell werden aufgrund Ihres uneingeschränkten Zugriffs auf dieadmin-Datenbank einige administrative Warnungen angezeigt. Weitere Informationen zum Einschränken dieses Zugriffs finden Sie unterHow To Install and Secure MongoDB on Ubuntu 16.04, wenn Sie in ein Produktionssetup wechseln.

Derzeit können Sie Ihren Zugriff auf die Datenbankadminverwenden, um einen Benutzer mit den BerechtigungenuserAdminAnyDatabasezu erstellen, der einen kennwortgeschützten Zugriff auf die Datenbanken Ihrer Anwendung ermöglicht.

Geben Sie in der Shell an, dass Sie die Datenbankadminzum Erstellen Ihres Benutzers verwenden möchten:

use admin

Erstellen Sie als Nächstes eine Rolle und ein Kennwort, indem Sie mit dem Befehldb.createUsereinen Benutzernamen und ein Kennwort hinzufügen. Nachdem Sie diesen Befehl eingegeben haben, stellt die Shell drei Punkte vor jede Zeile, bis der Befehl abgeschlossen ist. Stellen Sie sicher, dass Sie den hier angegebenen Benutzer und das Kennwort durch Ihren eigenen Benutzernamen und Ihr Kennwort ersetzen:

db.createUser(
  {
    user: "sammy",
    pwd: "your_password",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
  }
)

Dadurch wird ein Eintrag für den Benutzersammy in der Datenbankadminerstellt. Der von Ihnen ausgewählte Benutzername und dieadmin-Datenbank dienen Ihrem Benutzer als Bezeichner.

Die Ausgabe für den gesamten Prozess sieht folgendermaßen aus, einschließlich der Meldung, dass die Eingabe erfolgreich war:

Output> db.createUser(
...  {
...    user: "sammy",
...    pwd: "your_password",
...    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
...  }
...)
Successfully added user: {
        "user" : "sammy",
        "roles" : [
                {
                        "role" : "userAdminAnyDatabase",
                        "db" : "admin"
                }
        ]
}

Nachdem Sie Ihren Benutzer und Ihr Kennwort erstellt haben, können Sie die Mongo-Shell jetzt beenden:

exit

Nachdem Sie Ihren Datenbankbenutzer erstellt haben, können Sie den Code des Startprojekts klonen und die Mongoose-Bibliothek hinzufügen, mit der Sie Schemata und Modelle für die Sammlungen in Ihren Datenbanken implementieren können.

[[Schritt 2 - Hinzufügen von Mungo und Datenbankinformationen zum Projekt]] == Schritt 2 - Hinzufügen von Mungo- und Datenbankinformationen zum Projekt

Unsere nächsten Schritte werden darin bestehen, den Anwendungsstartcode zu klonen und Mongoose und unsere MongoDB-Datenbankinformationen zum Projekt hinzuzufügen.

Klonen Sie im Home-Verzeichnis Ihres Nicht-Root-Benutzers dienodejs-image-demo repository aus denDigitalOcean Community GitHub account. Dieses Repository enthält den Code aus dem inHow To Build a Node.js Application with Docker beschriebenen Setup.

Klonen Sie das Repository in ein Verzeichnis namensnode_project:

git clone https://github.com/do-community/nodejs-image-demo.git node_project

Wechseln Sie in das Verzeichnisnode_project:

cd  node_project

Bevor Sie den Projektcode ändern, werfen wir einen Blick auf die Projektstruktur mit dem Befehltree.

[.Hinweis]##

Tip:tree ist ein nützlicher Befehl zum Anzeigen von Datei- und Verzeichnisstrukturen über die Befehlszeile. Sie können es mit dem folgenden Befehl installieren:

sudo apt install tree

Um es zu verwenden, geben Siecd in ein bestimmtes Verzeichnis ein und geben Sietree ein. Sie können den Pfad zum Startpunkt auch mit einem Befehl wie dem folgenden angeben:

tree /home/sammy/sammys-project

Geben Sie Folgendes ein, um das Verzeichnisnode_projectanzuzeigen:

tree

Die Struktur des aktuellen Projekts sieht folgendermaßen aus:

Output├── Dockerfile
├── README.md
├── app.js
├── package-lock.json
├── package.json
└── views
    ├── css
    │   └── styles.css
    ├── index.html
    └── sharks.html

Wir werden diesem Projekt Verzeichnisse hinzufügen, während wir uns durch das Tutorial bewegen, undtree wird ein nützlicher Befehl sein, um unseren Fortschritt zu verfolgen.

Fügen Sie als Nächstes das npm-Paketmongoose mit dem Befehlnpm install zum Projekt hinzu:

npm install mongoose

Dieser Befehl erstellt einnode_modules-Verzeichnis in Ihrem Projektverzeichnis unter Verwendung der in derpackage.json-Datei des Projekts aufgeführten Abhängigkeiten und fügt diesem Verzeichnismongoose hinzu. Außerdem werdenmongoose zu den in Ihrerpackage.json-Datei aufgeführten Abhängigkeiten hinzugefügt. Eine ausführlichere Beschreibung vonpackage.json finden Sie unterStep 1 inHow To Build a Node.js Application with Docker.

Vor dem Erstellen von Mongoose-Schemas oder -Modellen fügen wir unsere Datenbankverbindungsinformationen hinzu, damit unsere Anwendung eine Verbindung zu unserer Datenbank herstellen kann.

Erstellen Sie eine separate Datei für Ihre Datenbankverbindungsinformationen mit dem Namendb.js, um die Bedenken Ihrer Anwendung so weit wie möglich zu trennen. Sie können diese Datei mitnano oder Ihrem bevorzugten Editor öffnen:

nano db.js

Importieren Sie zunächst diemongoosemodule mit der Funktionrequire:

~/node_project/db.js

const mongoose = require('mongoose');

Auf diese Weise erhalten Sie Zugriff auf die in Mongoose integrierten Methoden, mit denen Sie die Verbindung zu Ihrer Datenbank herstellen.

Fügen Sie als Nächstes die folgendenconstantshinzu, um Informationen für den Verbindungs-URI von Mongo zu definieren. Obwohl der Benutzername und das Passwort optional sind, werden sie eingeschlossen, damit wir eine Authentifizierung für unsere Datenbank verlangen können. Stellen Sie sicher, dass Sie den unten aufgeführten Benutzernamen und das Passwort durch Ihre eigenen Informationen ersetzen, und rufen Sie die Datenbank anders als'sharkinfo'an, wenn Sie Folgendes bevorzugen:

~/node_project/db.js

const mongoose = require('mongoose');

const MONGO_USERNAME = 'sammy';
const MONGO_PASSWORD = 'your_password';
const MONGO_HOSTNAME = '127.0.0.1';
const MONGO_PORT = '27017';
const MONGO_DB = 'sharkinfo';

Da wir unsere Datenbank lokal ausführen, haben wir127.0.0.1 als Hostnamen verwendet. Dies würde sich in anderen Entwicklungskontexten ändern: Wenn Sie beispielsweise einen separaten Datenbankserver verwenden oder mit mehreren Knoten in einem containerisierten Workflow arbeiten.

Definieren Sie abschließend eine Konstante für den URI und erstellen Sie die Verbindung mit der Methodemongoose.connect():

~/node_project/db.js

...
const url = `mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOSTNAME}:${MONGO_PORT}/${MONGO_DB}?authSource=admin`;

mongoose.connect(url, {useNewUrlParser: true});

Beachten Sie, dass wir in der URI dieauthSource für unseren Benutzer alsadmin-Datenbank angegeben haben. Dies ist erforderlich, da wir in unserer Verbindungszeichenfolge einen Benutzernamen angegeben haben. Die Verwendung desuseNewUrlParser-Flags mitmongoose.connect() gibt an, dass wir Mongosnew URL parser verwenden möchten.

Speichern und schließen Sie die Datei, wenn Sie mit der Bearbeitung fertig sind.

Fügen Sie als letzten Schritt die Datenbankverbindungsinformationen zur Dateiapp.jshinzu, damit die Anwendung sie verwenden kann. Öffnen Sieapp.js:

nano app.js

Die ersten Zeilen der Datei sehen folgendermaßen aus:

~/node_project/app.js

const express = require('express');
const app = express();
const router = express.Router();

const path = __dirname + '/views/';
...

Fügen Sie unterhalb der Konstantendefinition vonrouteram oberen Rand der Datei die folgende Zeile hinzu:

~/node_project/app.js

...
const router = express.Router();
const db = require('./db');

const path = __dirname + '/views/';
...

Dadurch wird die Anwendung angewiesen, die indb.js angegebenen Datenbankverbindungsinformationen zu verwenden.

Speichern und schließen Sie die Datei, wenn Sie mit der Bearbeitung fertig sind.

Wenn Ihre Datenbankinformationen vorhanden sind und Mongoose zu Ihrem Projekt hinzugefügt wurde, können Sie die Schemata und Modelle erstellen, die die Daten in Ihrersharks-Sammlung formen.

[[Schritt-3 - Erstellen von Mungo-Schemata und -Modellen]] == Schritt 3 - Erstellen von Mungo-Schemas und -Modellen

Unser nächster Schritt wird darin bestehen, über die Struktur dersharks-Sammlung nachzudenken, die Benutzer mit ihrer Eingabe in dersharkinfo-Datenbank erstellen. Welche Struktur sollen diese erstellten Dokumente haben? Die Hai-Informationsseite unserer aktuellen Anwendung enthält einige Details zu verschiedenen Haien und deren Verhalten:

Shark Info Page

In Übereinstimmung mit diesem Thema können Benutzer neue Haie mit Details zu ihrem Gesamtcharakter hinzufügen. Dieses Ziel wird bestimmen, wie wir unser Schema erstellen.

Erstellen Sie einmodels-Verzeichnis im aktuellen Projektverzeichnis, damit sich Ihre Schemas und Modelle von den anderen Teilen Ihrer Anwendung unterscheiden:

mkdir models

Öffnen Sie als Nächstes eine Datei mit dem Namensharks.js, um Ihr Schema und Modell zu erstellen:

nano models/sharks.js

Importieren Sie das Modulmongoose oben in die Datei:

~/node_project/models/sharks.js

const mongoose = require('mongoose');

Definieren Sie darunter einSchema-Objekt, das als Grundlage für Ihr Hai-Schema verwendet werden soll:

~/node_project/models/sharks.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

Sie können nun die Felder definieren, die Sie in Ihr Schema aufnehmen möchten. Da wir eine Sammlung mit einzelnen Haien und Informationen zu deren Verhalten erstellen möchten, geben wir einennamekey und einencharacter-Schlüssel an. Fügen Sie das folgendeShark-Schema unter Ihren Konstantendefinitionen hinzu:

~/node_project/models/sharks.js

...
const Shark = new Schema ({
        name: { type: String, required: true },
        character: { type: String, required: true },
});

Diese Definition enthält Informationen über die Art der Eingabe, die wir von Benutzern erwarten - in diesem Fall astring - und darüber, ob diese Eingabe erforderlich ist oder nicht.

Erstellen Sie abschließend dasShark-Modell mitmodel() function von Mongoose. Mit diesem Modell können Sie Dokumente aus Ihrer Sammlung abfragen und neue Dokumente validieren. Fügen Sie die folgende Zeile am Ende der Datei hinzu:

~/node_project/models/sharks.js

...
module.exports = mongoose.model('Shark', Shark)

Diese letzte Zeile stellt unserShark-Modell als Modul unter Verwendung dermodule.exports property zur Verfügung. Diese Eigenschaft definiert die Werte, die das Modul exportiert, sodass sie an anderer Stelle in der Anwendung verwendet werden können.

Die fertigemodels/sharks.js-Datei sieht folgendermaßen aus:

~/node_project/models/sharks.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const Shark = new Schema ({
        name: { type: String, required: true },
        character: { type: String, required: true },
});

module.exports = mongoose.model('Shark', Shark)

Speichern und schließen Sie die Datei, wenn Sie mit der Bearbeitung fertig sind.

Wenn das Schema und das Modell vonSharkvorhanden sind, können Sie mit der Arbeit an der Logik beginnen, die bestimmt, wie Ihre Anwendung Benutzereingaben verarbeitet.

[[Schritt-4 - Erstellen von Controllern]] == Schritt 4 - Erstellen von Controllern

Unser nächster Schritt wird darin bestehen, die Controller-Komponente zu erstellen, die bestimmt, wie Benutzereingaben in unserer Datenbank gespeichert und an den Benutzer zurückgegeben werden.

Erstellen Sie zunächst ein Verzeichnis für den Controller:

mkdir controllers

Öffnen Sie als Nächstes eine Datei in diesem Ordner mit dem Namensharks.js:

nano controllers/sharks.js

Am Anfang der Datei importieren wir das Modul mit unseremShark-Modell, damit wir es in der Logik unseres Controllers verwenden können. Wir importieren auch diepath module, um auf Dienstprogramme zuzugreifen, mit denen wir den Pfad zu dem Formular festlegen können, in das Benutzer ihre Haie eingeben.

Fügen Sie am Anfang der Datei die folgendenrequire-Funktionen hinzu:

~/node_project/controllers/sharks.js

const path = require('path');
const Shark = require('../models/sharks');

Als Nächstes schreiben wir eine Folge von Funktionen, die wir mit dem Controller-Modul unter Verwendung vonexports shortcutdes Knotens exportieren. Diese Funktionen umfassen die drei Aufgaben, die sich auf die Hai-Daten unserer Benutzer beziehen:

  • Senden Sie Benutzern das Haieingabeformular.

  • Einen neuen Haieintrag erstellen.

  • Anzeige der Haie zurück zu den Benutzern.

Erstellen Sie zunächst eineindex-Funktion, um die Hai-Seite mit dem Eingabeformular anzuzeigen. Fügen Sie diese Funktion unterhalb Ihrer Importe hinzu:

~/node_project/controllers/sharks.js

...
exports.index = function (req, res) {
    res.sendFile(path.resolve('views/sharks.html'));
};

Fügen Sie als Nächstes unterhalb derindex-Funktion eine Funktion namenscreate hinzu, um einen neuen Hai-Eintrag in Ihrersharks-Sammlung zu erstellen:

~/node_project/controllers/sharks.js

...
exports.create = function (req, res) {
    var newShark = new Shark(req.body);
    console.log(req.body);
    newShark.save(function (err) {
            if(err) {
            res.status(400).send('Unable to save shark to database');
        } else {
            res.redirect('/sharks/getshark');
        }
  });
               };

Diese Funktion wird aufgerufen, wenn ein Benutzer Hai-Daten in das Formular auf der Seitesharks.htmlendet. Wir werden die Route mit diesem POST-Endpunkt später im Lernprogramm erstellen, wenn wir die Routen unserer Anwendung erstellen. Mit denbody der POST-Anforderung erstellt unserecreate-Funktion ein neues Hai-Dokumentobjekt, hiernewShark genannt, unter Verwendung des von uns importiertenShark-Modells. Wir haben einconsole.log method hinzugefügt, um den Hai-Eintrag an die Konsole auszugeben und zu überprüfen, ob unsere POST-Methode wie beabsichtigt funktioniert. Sie können dies jedoch jederzeit weglassen, wenn Sie dies bevorzugen.

Unter Verwendung desnewShark-Objekts ruft diecreate-Funktion dannmodel.save() method von Mongoose auf, um ein neues Hai-Dokument mit den Schlüsseln zu erstellen, die Sie imShark-Modell definiert haben. Diesescallback function folgt demstandard Node callback pattern:callback(error, results). Im Fehlerfall senden wir eine Nachricht, in der der Fehler an unsere Benutzer gemeldet wird, und im Erfolgsfall senden wir dieres.redirect() method, um Benutzer an den Endpunkt zu senden, der ihnen ihre Hai-Informationen zurückgibt im Browser.

Schließlich zeigt die Funktionlistdem Benutzer den Inhalt der Sammlung wieder an. Fügen Sie den folgenden Code unter der Funktioncreatehinzu:

~/node_project/controllers/sharks.js

...
exports.list = function (req, res) {
        Shark.find({}).exec(function (err, sharks) {
                if (err) {
                        return res.send(500, err);
                }
                res.render('getshark', {
                        sharks: sharks
             });
        });
};

Diese Funktion verwendet das ModellSharkmitmodel.find() methodvon Mongoose, um die Haie zurückzugeben, die in die Sammlungsharkseingegeben wurden. Dazu wird das Abfrageobjekt - in diesem Fall alle Einträge in dersharks-Sammlung - als Versprechen unter Verwendung vonexec() function von Mongoose zurückgegeben. Im Fehlerfall sendet die Callback-Funktion einen 500-Fehler.

Das zurückgegebene Abfrageobjekt mit der Auflistungsharkswird auf einer Seitegetsharkgerendert, die wir im nächsten Schritt mit der VorlagenspracheEJSerstellen.

Die fertige Datei sieht folgendermaßen aus:

~/node_project/controllers/sharks.js

const path = require('path');
const Shark = require('../models/sharks');

exports.index = function (req, res) {
    res.sendFile(path.resolve('views/sharks.html'));
};

exports.create = function (req, res) {
    var newShark = new Shark(req.body);
    console.log(req.body);
    newShark.save(function (err) {
            if(err) {
            res.status(400).send('Unable to save shark to database');
        } else {
            res.redirect('/sharks/getshark');
        }
  });
               };

exports.list = function (req, res) {
        Shark.find({}).exec(function (err, sharks) {
                if (err) {
                        return res.send(500, err);
                }
                res.render('getshark', {
                        sharks: sharks
             });
        });
};

Beachten Sie, dass wir hier zwar nichtarrow functions verwenden, diese jedoch möglicherweise in Ihren eigenen Entwicklungsprozess einbeziehen möchten, wenn Sie diesen Code durchlaufen.

Speichern und schließen Sie die Datei, wenn Sie mit der Bearbeitung fertig sind.

Bevor Sie mit dem nächsten Schritt fortfahren, können Sietree erneut aus Ihremnode_project-Verzeichnis ausführen, um die Projektstruktur an dieser Stelle anzuzeigen. Dieses Mal werden wir der Kürze halbertree anweisen, das Verzeichnisnode_modules mit der Option-I wegzulassen:

tree -I node_modules

Mit den vorgenommenen Ergänzungen sieht die Struktur Ihres Projekts folgendermaßen aus:

Output├── Dockerfile
├── README.md
├── app.js
├── controllers
│   └── sharks.js
├── db.js
├── models
│   └── sharks.js
├── package-lock.json
├── package.json
└── views
    ├── css
    │   └── styles.css
    ├── index.html
    └── sharks.html

Nachdem Sie nun über eine Controller-Komponente verfügen, mit der Sie steuern können, wie Benutzereingaben gespeichert und an den Benutzer zurückgegeben werden, können Sie die Ansichten erstellen, die die Logik Ihres Controllers implementieren.

[[Schritt 5 - Verwenden von EJS-und Express-Middleware zum Sammeln und Rendern von Daten]] == Schritt 5 - Verwenden von EJS und Express Middleware zum Sammeln und Rendern von Daten

Damit unsere Anwendung mit Benutzerdaten arbeiten kann, werden wir zwei Dinge tun: Erstens werden wir eine integrierte Express-Middleware-Funktionurlencoded() einbinden, mit der unsere Anwendung die eingegebenen Daten unseres Benutzers analysieren kann. Zweitens werden wir unseren Ansichten Vorlagen-Tags hinzufügen, um eine dynamische Interaktion mit Benutzerdaten in unserem Code zu ermöglichen.

Um mit derurlencoded()-Funktion von Express zu arbeiten, öffnen Sie zuerst dieapp.js-Datei:

nano app.js

Fügen Sie über derexpress.static()-Funktion die folgende Zeile hinzu:

~/node_project/app.js

...
app.use(express.urlencoded({ extended: true }));
app.use(express.static(path));
...

Durch Hinzufügen dieser Funktion erhalten Sie Zugriff auf die analysierten POST-Daten aus unserem Hai-Informationsformular. Wir gebentrue mit der Optionextended an, um eine größere Flexibilität bei der Art der Daten zu ermöglichen, die unsere Anwendung analysiert (einschließlich verschachtelter Objekte). Weitere Informationen zu Optionen finden Sie infunction documentation.

Speichern und schließen Sie die Datei, wenn Sie mit der Bearbeitung fertig sind.

Als Nächstes werden wir unseren Ansichten Vorlagenfunktionen hinzufügen. Installieren Sie zuerstejs package mitnpm install:

npm install ejs

Öffnen Sie als Nächstes die Dateisharks.html im Ordnerviews:

nano views/sharks.html

In Schritt 3 haben wir uns diese Seite angesehen, um zu bestimmen, wie wir unser Mongoose-Schema und -Modell schreiben sollen:

Shark Info Page

Anstatt nun zwei Spaltenlayout zu haben, werden wir eine dritte Spalte mit einem Formular einführen, in das Benutzer Informationen über Haie eingeben können.

Ändern Sie als ersten Schritt die Abmessungen der vorhandenen Spalten in4, um drei gleich große Spalten zu erstellen. Beachten Sie, dass Sie diese Änderung in den beiden Zeilen vornehmen müssen, in denen derzeit<div class="col-lg-6"> angezeigt wird. Diese werden beide zu<div class="col-lg-4">:

~/node_project/views/sharks.html

...

Some sharks are known to be dangerous to humans, though many more are not. The sawshark, for example, is not considered a threat to humans.
Sawshark

Other sharks are known to be friendly and welcoming!
Sammy the Shark

Eine Einführung in das Bootstrap-Rastersystem, einschließlich der Zeilen- und Spaltenlayouts, finden Sie inintroduction to Bootstrap.

Fügen Sie als Nächstes eine weitere Spalte hinzu, die den benannten Endpunkt für die POST-Anforderung mit den Hai-Daten des Benutzers und den EJS-Vorlagen-Tags enthält, die diese Daten erfassen. Diese Spalte befindet sich unter den schließenden Tags</p> und</div> aus der vorhergehenden Spalte und über den schließenden Tags für die Zeile, den Container und das HTML-Dokument. Diese abschließenden Tags sind bereits in Ihrem Code vorhanden. Sie sind auch unten mit Kommentaren gekennzeichnet. Belassen Sie diese beim Hinzufügen des folgenden Codes, um die neue Spalte zu erstellen:

~/node_project/views/sharks.html

...
       

Enter Your Shark

Imform-Tag fügen Sie einen"/sharks/addshark"-Endpunkt für die Hai-Daten des Benutzers hinzu und geben die POST-Methode zum Senden an. In den Eingabefeldern geben Sie Felder für"Shark Name" und"Shark Character" an, die mit dem zuvor definierten Modell vonShark übereinstimmen.

Um die Benutzereingaben zu Ihrersharks-Sammlung hinzuzufügen, verwenden Sie EJS-Vorlagen-Tags (<%=,%>) zusammen mit der JavaScript-Syntax, um die Benutzereingaben den entsprechenden Feldern in der neu erstellten zuzuordnen Dokument. Weitere Informationen zu JavaScript-Objekten finden Sie in unserem Artikel zuUnderstanding JavaScript Objects. Weitere Informationen zu EJS-Vorlagen-Tags finden Sie inEJS documentation.

Der gesamte Container mit allen drei Spalten, einschließlich der Spalte mit dem Haieingabeformular, sieht abschließend folgendermaßen aus:

~/node_project/views/sharks.html

...

Some sharks are known to be dangerous to humans, though many more are not. The sawshark, for example, is not considered a threat to humans.
Sawshark

Other sharks are known to be friendly and welcoming!
Sammy the Shark

Enter Your Shark

Speichern und schließen Sie die Datei, wenn Sie mit der Bearbeitung fertig sind.

Nachdem Sie nun die Möglichkeit haben, die Eingaben Ihres Benutzers zu erfassen, können Sie einen Endpunkt erstellen, auf dem die zurückgegebenen Haie und die zugehörigen Zeicheninformationen angezeigt werden.

Kopieren Sie die neu geändertesharks.html-Datei in eine Datei mit dem Namengetshark.html:

cp views/sharks.html views/getshark.html

Öffnen Siegetshark.html:

nano views/getshark.html

In der Datei ändern wir die Spalte, die wir zum Erstellen unseres Haie-Eingabeformulars verwendet haben, indem wir sie durch eine Spalte ersetzen, in der die Haie in unserersharks-Sammlung angezeigt werden. Auch hier wird Ihr Code zwischen den vorhandenen Tags</p> und</div> aus der vorhergehenden Spalte und den schließenden Tags für die Zeile, den Container und das HTML-Dokument verschoben. Denken Sie daran, diese Tags beizubehalten, wenn Sie den folgenden Code zum Erstellen der Spalte hinzufügen:

~/node_project/views/getshark.html

...
       

Your Sharks
    <% sharks.forEach(function(shark) { %>

    Name: <%= shark.name %>

    Character: <%= shark.character %>

    <% }); %>

Hier verwenden Sie EJS-Vorlagen-Tags und dieforEach() method, um jeden Wert in Ihrersharks-Sammlung auszugeben, einschließlich Informationen zum zuletzt hinzugefügten Hai.

Der gesamte Container mit allen drei Spalten, einschließlich der Spalte mit Ihrersharks-Sammlung, sieht nach Abschluss folgendermaßen aus:

~/node_project/views/getshark.html

...

Some sharks are known to be dangerous to humans, though many more are not. The sawshark, for example, is not considered a threat to humans.
Sawshark

Other sharks are known to be friendly and welcoming!
Sammy the Shark

Your Sharks
    <% sharks.forEach(function(shark) { %>

    Name: <%= shark.name %>

    Character: <%= shark.character %>

    <% }); %>

Speichern und schließen Sie die Datei, wenn Sie mit der Bearbeitung fertig sind.

Damit die Anwendung die von Ihnen erstellten Vorlagen verwenden kann, müssen Sie Ihrerapp.js-Datei einige Zeilen hinzufügen. Öffne es wieder:

nano app.js

Fügen Sie über der Stelle, an der Sie die Funktionexpress.urlencoded()hinzugefügt haben, die folgenden Zeilen hinzu:

~/node_project/app.js

...
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.use(express.urlencoded({ extended: true }));
app.use(express.static(path));

...

Die Methodeapp.engine weist die Anwendung an, die EJS-Vorlagen-Engine HTML-Dateien zuzuordnen, währendapp.set die Standard-Ansichts-Engine definiert.

Die Dateiapp.jsollte nun folgendermaßen aussehen:

~/node_project/app.js

const express = require('express');
const app = express();
const router = express.Router();
const db = require('./db');

const path = __dirname + '/views/';
const port = 8080;

router.use(function (req,res,next) {
  console.log('/' + req.method);
  next();
});

router.get('/',function(req,res){
  res.sendFile(path + 'index.html');
});

router.get('/sharks',function(req,res){
  res.sendFile(path + 'sharks.html');
});

app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.use(express.urlencoded({ extended: true }));
app.use(express.static(path));
app.use('/', router);

app.listen(port, function () {
  console.log('Example app listening on port 8080!')
})

Nachdem Sie nun Ansichten erstellt haben, die dynamisch mit Benutzerdaten arbeiten können, ist es an der Zeit, die Routen Ihres Projekts zu erstellen, um Ihre Ansichten und die Steuerungslogik zusammenzuführen.

[[Schritt-6 - Erstellen von Routen]] == Schritt 6 - Erstellen von Routen

Der letzte Schritt beim Zusammenführen der Anwendungskomponenten besteht in der Erstellung von Routen. Wir werden unsere Routen nach Funktionen trennen, einschließlich einer Route zur Zielseite unserer Anwendung und einer anderen Route zu unserer Haifischseite. Auf unserersharks-Route integrieren wir die Logik unseres Controllers in die Ansichten, die wir im vorherigen Schritt erstellt haben.

Erstellen Sie zunächst einroutes-Verzeichnis:

mkdir routes

Öffnen Sie als Nächstes eine Datei mit dem Namenindex.js in diesem Verzeichnis:

nano routes/index.js

Diese Datei importiert zuerst die Objekteexpress,router undpath, sodass wir die Routen definieren können, die mit dem Objektrouter exportiert werden sollen, und dies ermöglichen Arbeiten Sie dynamisch mit Dateipfaden. Fügen Sie den folgenden Code oben in die Datei ein:

~/node_project/routes/index.js

const express = require('express');
const router = express.Router();
const path = require('path');

Fügen Sie als Nächstes die folgenderouter.use-Funktion hinzu, mit dermiddleware function geladen werden, mit der die Anforderungen des Routers protokolliert und an die Route der Anwendung weitergeleitet werden:

~/node_project/routes/index.js

...

router.use (function (req,res,next) {
  console.log('/' + req.method);
  next();
});

Anforderungen an das Stammverzeichnis unserer Anwendung werden zuerst hierher geleitet, und von hier aus werden Benutzer zur Zielseite unserer Anwendung geleitet, der Route, die wir als Nächstes definieren. Fügen Sie den folgenden Code unter der Funktionrouter.usehinzu, um die Route zur Zielseite zu definieren:

~/node_project/routes/index.js

...

router.get('/',function(req,res){
  res.sendFile(path.resolve('views/index.html'));
});

Wenn Benutzer unsere Anwendung besuchen, möchten wir sie zunächst an die Zielseite vonindex.htmlenden, die sich in unserem Verzeichnisviewsbefindet.

Um diese Routen als importierbare Module an anderer Stelle in der Anwendung zugänglich zu machen, fügen Sie am Ende der Datei einen schließenden Ausdruck hinzu, um das Objektrouterzu exportieren:

~/node_project/routes/index.js

...

module.exports = router;

Die fertige Datei sieht folgendermaßen aus:

~/node_project/routes/index.js

const express = require('express');
const router = express.Router();
const path = require('path');

router.use (function (req,res,next) {
  console.log('/' + req.method);
  next();
});

router.get('/',function(req,res){
  res.sendFile(path.resolve('views/index.html'));
});

module.exports = router;

Speichern und schließen Sie diese Datei, wenn Sie mit der Bearbeitung fertig sind.

Öffnen Sie als Nächstes eine Datei mit dem Namensharks.js, um zu definieren, wie die Anwendung die verschiedenen Endpunkte und Ansichten verwenden soll, die wir erstellt haben, um mit der Haieingabe unseres Benutzers zu arbeiten:

nano routes/sharks.js

Importieren Sie oben in der Datei die Objekteexpress undrouter:

~/node_project/routes/sharks.js

const express = require('express');
const router = express.Router();

Importieren Sie als Nächstes ein Modul namensshark, mit dem Sie mit den exportierten Funktionen arbeiten können, die Sie mit Ihrem Controller definiert haben:

~/node_project/routes/sharks.js

const express = require('express');
const router = express.Router();
const shark = require('../controllers/sharks');

Jetzt können Sie Routen mit den Funktionenindex,create undlisterstellen, die Sie in Ihrer Controller-Dateisharksdefiniert haben. Jede Route wird mit der entsprechenden HTTP-Methode verknüpft: GET für den Fall, dass die Hauptzielseite mit den Haiinformationen angezeigt wird und die Liste der Haie an den Benutzer zurückgegeben wird, und POST für den Fall, dass ein neuer Haieintrag erstellt wird:

~/node_project/routes/sharks.js

...

router.get('/', function(req, res){
    shark.index(req,res);
});

router.post('/addshark', function(req, res) {
    shark.create(req,res);
});

router.get('/getshark', function(req, res) {
    shark.list(req,res);
});

Jede Route verwendet die zugehörige Funktion incontrollers/sharks.js, da wir dieses Modul zugänglich gemacht haben, indem wir es oben in diese Datei importiert haben.

Schließen Sie abschließend die Datei, indem Sie diese Routen an das Objektrouteranhängen und exportieren:

~/node_project/routes/index.js

...

module.exports = router;

Die fertige Datei sieht folgendermaßen aus:

~/node_project/routes/sharks.js

const express = require('express');
const router = express.Router();
const shark = require('../controllers/sharks');

router.get('/', function(req, res){
    shark.index(req,res);
});

router.post('/addshark', function(req, res) {
    shark.create(req,res);
});

router.get('/getshark', function(req, res) {
    shark.list(req,res);
});

module.exports = router;

Speichern und schließen Sie die Datei, wenn Sie mit der Bearbeitung fertig sind.

Der letzte Schritt, um diese Routen für Ihre Anwendung zugänglich zu machen, besteht darin, sie zuapp.js hinzuzufügen. Öffne diese Datei erneut:

nano app.js

Fügen Sie unterhalb Ihrerdb-Konstante den folgenden Import für Ihre Routen hinzu:

~/node_project/app.js

...
const db = require('./db');
const sharks = require('./routes/sharks');

Als nächstes istreplacedie Funktionapp.use, mit der Ihrrouter-Objekt derzeit in der folgenden Zeile bereitgestellt wird, in der das Routermodulsharksbereitgestellt wird:

~/node_project/app.js

...
app.use(express.static(path));
app.use('/sharks', sharks);

app.listen(port, function () {
        console.log("Example app listening on port 8080!")
})

Sie können jetzt die Routen löschen, die zuvor in dieser Datei definiert wurden, da Sie die Routen Ihrer Anwendung mit dem Routermodulsharksimportieren.

Die endgültige Version Ihrerapp.js-Datei sieht folgendermaßen aus:

~/node_project/app.js

const express = require('express');
const app = express();
const router = express.Router();
const db = require('./db');
const sharks = require('./routes/sharks');

const path = __dirname + '/views/';
const port = 8080;

app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.use(express.urlencoded({ extended: true }));
app.use(express.static(path));
app.use('/sharks', sharks);

app.listen(port, function () {
  console.log('Example app listening on port 8080!')
})

Speichern und schließen Sie die Datei, wenn Sie mit der Bearbeitung fertig sind.

Sie können jetzttree erneut ausführen, um die endgültige Struktur Ihres Projekts anzuzeigen:

tree -I node_modules

Ihre Projektstruktur sieht nun folgendermaßen aus:

Output├── Dockerfile
├── README.md
├── app.js
├── controllers
│   └── sharks.js
├── db.js
├── models
│   └── sharks.js
├── package-lock.json
├── package.json
├── routes
│   ├── index.js
│   └── sharks.js
└── views
    ├── css
    │   └── styles.css
    ├── getshark.html
    ├── index.html
    └── sharks.html

Nachdem Sie alle Ihre Anwendungskomponenten erstellt und installiert haben, können Sie Ihrer Datenbank jetzt einen Testhai hinzufügen!

Wenn Sie das Lernprogramm zur Ersteinrichtung des Servers in den Voraussetzungen befolgt haben, müssen Sie Ihre Firewall ändern, da derzeit nur SSH-Datenverkehr zulässig ist. So lassen Sie den Datenverkehr zu Port8080laufen:

sudo ufw allow 8080

Starten Sie die Anwendung:

node app.js

Navigieren Sie anschließend mit Ihrem Browser zuhttp://your_server_ip:8080. Sie sehen die folgende Zielseite:

Application Landing Page

Klicken Sie auf die SchaltflächeGet Shark Info. Sie sehen die folgende Informationsseite mit dem hinzugefügten Haieingabeformular:

Shark Info Form

Fügen Sie in das Formular einen Hai Ihrer Wahl ein. Für diese Demonstration fügen wirMegalodon Shark zum FeldShark Name undAncient zum FeldShark Character hinzu:

Filled Shark Form

Klicken Sie auf die SchaltflächeSubmit. Sie sehen eine Seite mit diesen Hai-Informationen, die Ihnen wieder angezeigt werden:

Shark Output

Außerdem wird in Ihrer Konsole angezeigt, dass der Hai Ihrer Sammlung hinzugefügt wurde:

OutputExample app listening on port 8080!
{ name: 'Megalodon Shark', character: 'Ancient' }

Wenn Sie einen neuen Hai-Eintrag erstellen möchten, kehren Sie zur SeiteSharkszurück und wiederholen Sie den Vorgang des Hinzufügens eines Hais.

Sie haben jetzt eine funktionierende Hai-Informationsanwendung, mit der Benutzer Informationen zu ihren Lieblingshaien hinzufügen können.

Fazit

In diesem Lernprogramm haben Sie eine Node-Anwendung erstellt, indem Sie eine MongoDB-Datenbank integriert und die Anwendungslogik mithilfe des MVC-Architekturmusters neu geschrieben haben. Diese Anwendung kann als guter Ausgangspunkt für eine vollwertigeCRUD-Anwendung dienen.

Weitere Informationen zur Arbeit mit MongoDB finden Sie in unserer Bibliothek mittutorials on MongoDB.

Related