MongoDBをノードアプリケーションと統合する方法
序章
Node.js を使用していると、データを保存してクエリするプロジェクトを開発していることに気付くかもしれません。 この場合、アプリケーションのデータとクエリの種類に適したデータベースソリューションを選択する必要があります。
このチュートリアルでは、MongoDBデータベースを既存のノードアプリケーションと統合します。 MongoDBのようなNoSQLデータベースは、データ要件にスケーラビリティと柔軟性が含まれている場合に役立ちます。 MongoDBは、 JSON オブジェクトと非同期で動作するように設計されているため、Nodeともうまく統合できます。
MongoDBをプロジェクトに統合するには、 Object Document Mapper (ODM) Mongoose を使用して、アプリケーションデータのスキーマとモデルを作成します。 これにより、 model-view-controller(MVC)アーキテクチャパターンに従ってアプリケーションコードを整理できます。これにより、アプリケーションがユーザー入力を処理する方法のロジックを、データの構造化およびレンダリング方法から分離できます。ユーザー。 このパターンを使用すると、関心の分離をコードベースに導入することで、将来のテストと開発を容易にすることができます。
チュートリアルの最後に、お気に入りのサメに関するユーザーの入力を受け取り、結果をブラウザーに表示する、機能するサメ情報アプリケーションがあります。
前提条件
- Ubuntu 18.04を実行しているローカル開発マシンまたはサーバーと、root以外のユーザー
sudo
特権とアクティブなファイアウォール。 18.04サーバーでこれらをセットアップする方法のガイダンスについては、この初期サーバーセットアップガイドを参照してください。 - Node.jsとnpmがマシンまたはサーバーにインストールされ、NodeSourceによって管理されるPPAを使用してインストールするためのこれらの手順に従います。
- Ubuntu 18.04にMongoDBをインストールする方法のステップ1に従って、マシンまたはサーバーにMongoDBをインストールします。
ステップ1—Mongoユーザーを作成する
アプリケーションコードの操作を開始する前に、アプリケーションのデータベースにアクセスできる管理ユーザーを作成します。 このユーザーには、任意のデータベースに対する管理者権限があり、必要に応じて新しいデータベースを切り替えて作成する柔軟性が得られます。
まず、MongoDBがサーバーで実行されていることを確認します。
- sudo systemctl status mongodb
次の出力は、MongoDBが実行されていることを示しています。
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
...
次に、Mongoシェルを開いてユーザーを作成します。
- mongo
これにより、管理シェルに移動します。
OutputMongoDB shell version v3.6.3
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.3
...
>
シェルへの無制限のアクセスにより、シェルを開くと、いくつかの管理上の警告が表示されます。 admin
データベース。 このアクセスの制限について詳しくは、 Ubuntu 16.04にMongoDBをインストールして保護する方法を読んで、本番環境に移行する際に確認してください。
今のところ、あなたはへのアクセスを使用することができます admin
データベースを使用して、 userAdminAnyDatabase 権限を持つユーザーを作成します。これにより、アプリケーションのデータベースへのパスワードで保護されたアクセスが可能になります。
シェルで、使用することを指定します admin
ユーザーを作成するためのデータベース:
- use admin
次に、ユーザー名とパスワードを追加して、役割とパスワードを作成します。 db.createUser
指図。 このコマンドを入力すると、コマンドが完了するまで、シェルは各行の前に3つのドットを追加します。 ここに記載されているユーザーとパスワードは、必ず自分のユーザー名とパスワードに置き換えてください。
- db.createUser(
- {
- user: "sammy",
- pwd: "your_password",
- roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
- }
- )
これにより、ユーザーのエントリが作成されます sammy
の中に admin
データベース。 選択したユーザー名と admin
データベースはユーザーの識別子として機能します。
プロセス全体の出力は次のようになります。これには、エントリが成功したことを示すメッセージが含まれます。
Output> db.createUser(
... {
... user: "sammy",
... pwd: "your_password",
... roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
... }
...)
Successfully added user: {
"user" : "sammy",
"roles" : [
{
"role" : "userAdminAnyDatabase",
"db" : "admin"
}
]
}
ユーザーとパスワードを作成したら、Mongoシェルを終了できます。
- exit
データベースユーザーを作成したので、スタータープロジェクトコードのクローンを作成し、Mongooseライブラリを追加します。これにより、データベース内のコレクションのスキーマとモデルを実装できます。
ステップ2—マングースとデータベースの情報をプロジェクトに追加する
次のステップは、アプリケーションスターターコードのクローンを作成し、MongooseとMongoDBデータベース情報をプロジェクトに追加することです。
root以外のユーザーのホームディレクトリで、 DigitalOceanCommunityGitHubアカウントからnodejs-image-demoリポジトリのクローンを作成します。 このリポジトリには、Dockerを使用してNode.jsアプリケーションを構築する方法で説明されているセットアップのコードが含まれています。
リポジトリをと呼ばれるディレクトリに複製します node_project
:
- git clone https://github.com/do-community/nodejs-image-demo.git node_project
に変更します node_project
ディレクトリ:
- cd node_project
プロジェクトコードを変更する前に、を使用してプロジェクトの構造を見てみましょう。 tree
指図。
ヒント: tree
コマンドラインからファイルとディレクトリの構造を表示するための便利なコマンドです。 次のコマンドでインストールできます。
- sudo apt install tree
使用するには、 cd
指定されたディレクトリに入力し、次のように入力します tree
. 次のようなコマンドを使用して、開始点へのパスを指定することもできます。
- tree /home/sammy/sammys-project
次のように入力して、 node_project
ディレクトリ:
- tree
現在のプロジェクトの構造は次のようになります。
Output├── Dockerfile
├── README.md
├── app.js
├── package-lock.json
├── package.json
└── views
├── css
│ └── styles.css
├── index.html
└── sharks.html
チュートリアルを進めながら、このプロジェクトにディレクトリを追加します。 tree
進捗状況を追跡するのに役立つコマンドになります。
次に、 mongoose
プロジェクトへのnpmパッケージ npm install
指図:
- npm install mongoose
このコマンドは、 node_modules
プロジェクトのディレクトリにリストされている依存関係を使用して、プロジェクトディレクトリ内のディレクトリ package.json
ファイル、および追加します mongoose
そのディレクトリに。 また、追加されます mongoose
にリストされている依存関係に package.json
ファイル。 のより詳細な議論のために package.json
、Dockerを使用してNode.jsアプリケーションを構築する方法のステップ1を参照してください。
Mongooseスキーマまたはモデルを作成する前に、アプリケーションがデータベースに接続できるように、データベース接続情報を追加します。
アプリケーションの懸念事項を可能な限り分離するために、データベース接続情報用に次のような別のファイルを作成します。 db.js
. このファイルは次のコマンドで開くことができます nano
またはお気に入りの編集者:
- nano db.js
まず、インポートします mongoose
モジュールを使用して require
関数:
const mongoose = require('mongoose');
これにより、データベースへの接続を作成するために使用するMongooseの組み込みメソッドにアクセスできるようになります。
次に、次の定数を追加して、Mongoの接続URIの情報を定義します。 ユーザー名とパスワードはオプションですが、データベースの認証を要求できるように、これらを含めます。 以下にリストされているユーザー名とパスワードを自分の情報に置き換えてください。データベースを他の名前で自由に呼び出してください。 'sharkinfo'
必要に応じて:
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';
データベースをローカルで実行しているため、 127.0.0.1
ホスト名として。 これは、他の開発コンテキストで変更されます。たとえば、個別のデータベースサーバーを使用している場合や、コンテナー化されたワークフローで複数のノードを操作している場合などです。
最後に、URIの定数を定義し、 mongoose.connect()メソッドを使用して接続を作成します。
...
const url = `mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOSTNAME}:${MONGO_PORT}/${MONGO_DB}?authSource=admin`;
mongoose.connect(url, {useNewUrlParser: true});
URIで指定したことに注意してください authSource
私たちのユーザーのために admin
データベース。 これは、接続文字列にユーザー名を指定したために必要です。 を使用して useNewUrlParser
フラグ mongoose.connect()
Mongoの新しいURLパーサーを使用することを指定します。
編集が終了したら、ファイルを保存して閉じます。
最後のステップとして、データベース接続情報をに追加します app.js
アプリケーションがそれを使用できるようにファイルします。 開ける app.js
:
- nano app.js
ファイルの最初の行は次のようになります。
const express = require('express');
const app = express();
const router = express.Router();
const path = __dirname + '/views/';
...
下 router
ファイルの先頭近くにある定数定義に、次の行を追加します。
...
const router = express.Router();
const db = require('./db');
const path = __dirname + '/views/';
...
これは、で指定されたデータベース接続情報を使用するようにアプリケーションに指示します。 db.js
.
編集が終了したら、ファイルを保存して閉じます。
データベース情報を配置し、Mongooseをプロジェクトに追加すると、データを形成するスキーマとモデルを作成する準備が整います。 sharks
コレクション。
ステップ3—マングースのスキーマとモデルを作成する
次のステップは、 sharks
ユーザーが作成するコレクション sharkinfo
それらの入力を持つデータベース。 これらの作成されたドキュメントにどのような構造を持たせたいですか? 現在のアプリケーションのサメ情報ページには、さまざまなサメとその行動に関する詳細が含まれています。
このテーマに沿って、ユーザーに全体的な性格の詳細を含む新しいサメを追加してもらうことができます。 この目標は、スキーマの作成方法を形作ります。
スキーマとモデルをアプリケーションの他の部分と区別するために、 models
現在のプロジェクトディレクトリ内のディレクトリ:
- mkdir models
次に、というファイルを開きます sharks.js
スキーマとモデルを作成するには:
- nano models/sharks.js
をインポートします mongoose
ファイルの先頭にあるモジュール:
const mongoose = require('mongoose');
この下に、 Schema
sharkスキーマの基礎として使用するオブジェクト:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
これで、スキーマに含めるフィールドを定義できます。 個々のサメとその行動に関する情報を含むコレクションを作成したいので、 name
キーと character
鍵。 以下を追加します Shark
定数定義の下のスキーマ:
...
const Shark = new Schema ({
name: { type: String, required: true },
character: { type: String, required: true },
});
この定義には、ユーザーに期待される入力のタイプ(この場合は、 string )と、その入力が必要かどうかに関する情報が含まれています。
最後に、 Shark
Mongooseのmodel()関数を使用したモデル。 このモデルを使用すると、コレクションからドキュメントをクエリして、新しいドキュメントを検証できます。 ファイルの最後に次の行を追加します。
...
module.exports = mongoose.model('Shark', Shark)
この最後の行は私たちを作ります Shark
module.exportsプロパティを使用してモジュールとして利用可能なモデル。 このプロパティは、モジュールがエクスポートする値を定義し、アプリケーションの他の場所で使用できるようにします。
完成した 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)
編集が終了したら、ファイルを保存して閉じます。
とともに Shark
スキーマとモデルが整ったら、アプリケーションがユーザー入力を処理する方法を決定するロジックの作業を開始できます。
ステップ4—コントローラーの作成
次のステップは、ユーザー入力をデータベースに保存してユーザーに返す方法を決定するコントローラーコンポーネントを作成することです。
まず、コントローラーのディレクトリを作成します。
- mkdir controllers
次に、そのフォルダ内のファイルを開きます。 sharks.js
:
- nano controllers/sharks.js
ファイルの先頭に、モジュールをインポートします。 Shark
コントローラのロジックで使用できるようにモデル化します。 また、パスモジュールをインポートして、ユーザーがサメを入力するフォームへのパスを設定できるユーティリティにアクセスします。
以下を追加します require
ファイルの先頭まで機能します。
const path = require('path');
const Shark = require('../models/sharks');
次に、ノードのエクスポートショートカットを使用して、コントローラーモジュールでエクスポートする一連の関数を記述します。 これらの関数には、ユーザーのサメデータに関連する3つのタスクが含まれます。
- ユーザーにサメの入力フォームを送信します。
- 新しいサメのエントリを作成します。
- サメをユーザーに表示します。
まず、作成します index
入力フォームでサメのページを表示する関数。 インポートの下にこの関数を追加します。
...
exports.index = function (req, res) {
res.sendFile(path.resolve('views/sharks.html'));
};
次に、以下 index
関数、と呼ばれる関数を追加します create
あなたの新しいサメのエントリを作成するには sharks
コレクション:
...
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');
}
});
};
この関数は、ユーザーがサメのデータをフォームに投稿したときに呼び出されます。 sharks.html
ページ。 チュートリアルの後半でアプリケーションのルートを作成するときに、このPOSTエンドポイントを使用してルートを作成します。 とともに body
POSTリクエストの create
関数は、ここでは呼ばれる新しいサメドキュメントオブジェクトを作成します newShark
、を使用して Shark
インポートしたモデル。 POSTメソッドが意図したとおりに機能していることを確認するために、コンソールにsharkエントリを出力する console.logメソッドを追加しましたが、必要に応じてこれを省略してください。
を使用して newShark
オブジェクト、 create
次に、関数はMongooseの model.save()メソッドを呼び出し、で定義したキーを使用して新しいサメのドキュメントを作成します。 Shark
モデル。 このコールバック関数は、標準ノードコールバックパターンに従います。 callback(error, results)
. エラーの場合は、エラーを報告するメッセージをユーザーに送信し、成功した場合は、 res.redirect()メソッドを使用して、ユーザーをエンドポイントに送信します。彼らのサメの情報をブラウザで彼らに返します。
最後に、 list
関数は、コレクションのコンテンツをユーザーに表示します。 以下のコードを追加します create
関数:
...
exports.list = function (req, res) {
Shark.find({}).exec(function (err, sharks) {
if (err) {
return res.send(500, err);
}
res.render('getshark', {
sharks: sharks
});
});
};
この関数は、 Shark
マングースのmodel.find()メソッドを使用してモデル化し、入力されたサメを返します。 sharks
コレクション。 これは、クエリオブジェクトを返すことによって行われます。この場合、 sharks
コレクション—約束として、Mongooseの exec()関数を使用します。 エラーの場合、コールバック関数は500エラーを送信します。
返されたクエリオブジェクト sharks
コレクションはでレンダリングされます getshark
次のステップでEJSテンプレート言語を使用して作成するページ。
完成したファイルは次のようになります。
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
});
});
};
ここでは矢印関数を使用していませんが、独自の開発プロセスでこのコードを反復処理するときに、それらを含めることをお勧めします。
編集が終了したら、ファイルを保存して閉じます。
次のステップに進む前に、次の手順を実行できます tree
再びあなたから node_project
この時点でプロジェクトの構造を表示するディレクトリ。 今回は、簡潔にするために、 tree
省略します node_modules
を使用するディレクトリ -I
オプション:
- tree -I node_modules
追加を行うと、プロジェクトの構造は次のようになります。
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
これで、ユーザー入力を保存してユーザーに返す方法を指示するコントローラーコンポーネントができたので、コントローラーのロジックを実装するビューの作成に進むことができます。
ステップ5—EJSおよびExpressミドルウェアを使用したデータの収集とレンダリング
アプリケーションがユーザーデータを処理できるようにするために、2つのことを行います。1つは、アプリケーションがユーザーの入力データを解析できるようにする組み込みのExpressミドルウェア関数 urlencoded()を含めることです。 。 次に、ビューにテンプレートタグを追加して、コード内のユーザーデータとの動的な相互作用を可能にします。
Expressと連携するには urlencoded()
機能、最初にあなたの app.js
ファイル:
- nano app.js
あなたの上に express.static()
関数、次の行を追加します。
...
app.use(express.urlencoded({ extended: true }));
app.use(express.static(path));
...
この関数を追加すると、サメ情報フォームから解析されたPOSTデータにアクセスできるようになります。 指定しています true
とともに extended
アプリケーションが解析するデータのタイプ(ネストされたオブジェクトなどを含む)の柔軟性を高めるためのオプション。 オプションの詳細については、機能ドキュメントを参照してください。
編集が終了したら、ファイルを保存して閉じます。
次に、ビューにテンプレート機能を追加します。 まず、ejsパッケージをインストールします。 npm install
:
- npm install ejs
次に、 sharks.html
のファイル views
フォルダ:
- nano views/sharks.html
ステップ3では、このページを見て、マングースのスキーマとモデルをどのように作成するかを決定しました。
ここでは、2列の layout ではなく、ユーザーがサメに関する情報を入力できるフォームを備えた3番目の列を紹介します。
最初のステップとして、既存の列の寸法を次のように変更します 4
3つの同じサイズの列を作成します。 現在読んでいる2行でこの変更を行う必要があることに注意してください <div class="col-lg-6">
. これらは両方ともなります <div class="col-lg-4">
:
...
<div class="container">
<div class="row">
<div class="col-lg-4">
<p>
<div class="caption">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.
</div>
<img src="https://assets.digitalocean.com/articles/docker_node_image/sawshark.jpg" alt="Sawshark">
</p>
</div>
<div class="col-lg-4">
<p>
<div class="caption">Other sharks are known to be friendly and welcoming!</div>
<img src="https://assets.digitalocean.com/articles/docker_node_image/sammy.png" alt="Sammy the Shark">
</p>
</div>
</div>
</div>
</html>
行と列のレイアウトを含むBootstrapのグリッドシステムの概要については、このBootstrapの概要を参照してください。
次に、POSTリクエストの名前付きエンドポイントを含む別の列を追加します。この列には、ユーザーのsharkデータとそのデータをキャプチャするEJSテンプレートタグが含まれます。 このコラムはクロージングを下回ります </p>
と </div>
前の列のタグで、行、コンテナ、およびHTMLドキュメントの終了タグの上にあります。 これらの終了タグは、コードにすでに配置されています。 それらはまたコメントで下にマークされています。 次のコードを追加して新しい列を作成するときは、そのままにしておきます。
...
</p> <!-- closing p from previous column -->
</div> <!-- closing div from previous column -->
<div class="col-lg-4">
<p>
<form action="/sharks/addshark" method="post">
<div class="caption">Enter Your Shark</div>
<input type="text" placeholder="Shark Name" name="name" <%=sharks[i].name; %>
<input type="text" placeholder="Shark Character" name="character" <%=sharks[i].character; %>
<button type="submit">Submit</button>
</form>
</p>
</div>
</div> <!-- closing div for row -->
</div> <!-- closing div for container -->
</html> <!-- closing html tag -->
の中に form
タグ、あなたは追加しています "/sharks/addshark"
ユーザーのサメデータのエンドポイントと、それを送信するPOSTメソッドを指定します。 入力フィールドでは、次のフィールドを指定しています。 "Shark Name"
と "Shark Character"
、に合わせて Shark
前に定義したモデル。
ユーザー入力をに追加するには sharks
コレクション、EJSテンプレートタグを使用しています(<%=
, %>
)JavaScript構文とともに、ユーザーのエントリを新しく作成されたドキュメントの適切なフィールドにマップします。 JavaScriptオブジェクトの詳細については、JavaScriptオブジェクトについての記事を参照してください。 EJSテンプレートタグの詳細については、EJSドキュメントを参照してください。
shark入力フォームの列を含む、3つの列すべてを含むコンテナ全体は、終了すると次のようになります。
...
<div class="container">
<div class="row">
<div class="col-lg-4">
<p>
<div class="caption">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.
</div>
<img src="https://assets.digitalocean.com/articles/docker_node_image/sawshark.jpg" alt="Sawshark">
</p>
</div>
<div class="col-lg-4">
<p>
<div class="caption">Other sharks are known to be friendly and welcoming!</div>
<img src="https://assets.digitalocean.com/articles/docker_node_image/sammy.png" alt="Sammy the Shark">
</p>
</div>
<div class="col-lg-4">
<p>
<form action="/sharks/addshark" method="post">
<div class="caption">Enter Your Shark</div>
<input type="text" placeholder="Shark Name" name="name" <%=sharks[i].name; %>
<input type="text" placeholder="Shark Character" name="character" <%=sharks[i].character; %>
<button type="submit">Submit</button>
</form>
</p>
</div>
</div>
</div>
</html>
編集が終了したら、ファイルを保存して閉じます。
ユーザーの入力を収集する方法ができたので、返されたサメとそれに関連するキャラクター情報を表示するエンドポイントを作成できます。
新しく変更したものをコピーします sharks.html
と呼ばれるファイルへのファイル getshark.html
:
- cp views/sharks.html views/getshark.html
開ける getshark.html
:
- nano views/getshark.html
ファイル内で、サメの入力フォームを作成するために使用した列を、サメを表示する列に置き換えることで変更します。 sharks
コレクション。 繰り返しますが、コードは既存のものの間に入ります </p>
と </div>
前の列のタグと、行、コンテナ、およびHTMLドキュメントの終了タグ。 次のコードを追加して列を作成するときは、これらのタグをそのままにしておくことを忘れないでください。
...
</p> <!-- closing p from previous column -->
</div> <!-- closing div from previous column -->
<div class="col-lg-4">
<p>
<div class="caption">Your Sharks</div>
<ul>
<% sharks.forEach(function(shark) { %>
<p>Name: <%= shark.name %></p>
<p>Character: <%= shark.character %></p>
<% }); %>
</ul>
</p>
</div>
</div> <!-- closing div for row -->
</div> <!-- closing div for container -->
</html> <!-- closing html tag -->
ここでは、EJSテンプレートタグと forEach()メソッドを使用して、各値を出力しています。 sharks
最近追加されたサメに関する情報を含むコレクション。
3つの列すべてを含むコンテナ全体( sharks
コレクションは、終了すると次のようになります。
...
<div class="container">
<div class="row">
<div class="col-lg-4">
<p>
<div class="caption">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.
</div>
<img src="https://assets.digitalocean.com/articles/docker_node_image/sawshark.jpg" alt="Sawshark">
</p>
</div>
<div class="col-lg-4">
<p>
<div class="caption">Other sharks are known to be friendly and welcoming!</div>
<img src="https://assets.digitalocean.com/articles/docker_node_image/sammy.png" alt="Sammy the Shark">
</p>
</div>
<div class="col-lg-4">
<p>
<div class="caption">Your Sharks</div>
<ul>
<% sharks.forEach(function(shark) { %>
<p>Name: <%= shark.name %></p>
<p>Character: <%= shark.character %></p>
<% }); %>
</ul>
</p>
</div>
</div>
</div>
</html>
編集が終了したら、ファイルを保存して閉じます。
作成したテンプレートをアプリケーションで使用するには、数行を追加する必要があります。 app.js
ファイル。 もう一度開きます。
- nano app.js
追加した場所の上 express.urlencoded()
関数、次の行を追加します。
...
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'html');
app.use(express.urlencoded({ extended: true }));
app.use(express.static(path));
...
app.engine メソッドは、EJSテンプレートエンジンをHTMLファイルにマップするようにアプリケーションに指示します。 app.set は、デフォルトのビューエンジンを定義します。
君の 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!')
})
ユーザーデータを動的に操作できるビューを作成したので、次に、プロジェクトのルートを作成して、ビューとコントローラーロジックをまとめます。
ステップ6—ルートを作成する
アプリケーションのコンポーネントをまとめる最後のステップは、ルートを作成することです。 アプリケーションのランディングページへのルートとサメのページへの別のルートを含め、機能ごとにルートを分けます。 私たちの sharks
ルートは、コントローラーのロジックを前のステップで作成したビューと統合する場所になります。
まず、作成します routes
ディレクトリ:
- mkdir routes
次に、というファイルを開きます index.js
このディレクトリ内:
- nano routes/index.js
このファイルは最初に express
, router
、 と path
オブジェクトを使用して、エクスポートするルートを定義できます。 router
オブジェクト、およびファイルパスを動的に操作できるようにします。 ファイルの先頭に次のコードを追加します。
const express = require('express');
const router = express.Router();
const path = require('path');
次に、以下を追加します router.use
関数。ルーターの要求をログに記録してアプリケーションのルートに渡すミドルウェア関数をロードします。
...
router.use (function (req,res,next) {
console.log('/' + req.method);
next();
});
アプリケーションのルートへのリクエストは最初にここに送信され、ここからユーザーはアプリケーションのランディングページ(次に定義するルート)に移動します。 以下のコードを追加します router.use
ランディングページへのルートを定義する関数:
...
router.get('/',function(req,res){
res.sendFile(path.resolve('views/index.html'));
});
ユーザーがアプリケーションにアクセスしたときに、最初に送信したいのは index.html
私たちが持っているランディングページ views
ディレクトリ。
最後に、これらのルートをアプリケーションの他の場所にインポート可能なモジュールとしてアクセスできるようにするには、ファイルの最後に終了式を追加して、 router
物体:
...
module.exports = router;
完成したファイルは次のようになります。
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;
編集が終了したら、このファイルを保存して閉じます。
次に、というファイルを開きます sharks.js
ユーザーのサメの入力を処理するために作成したさまざまなエンドポイントとビューをアプリケーションがどのように使用するかを定義するには、次のようにします。
- nano routes/sharks.js
ファイルの先頭で、 express
と router
オブジェクト:
const express = require('express');
const router = express.Router();
次に、というモジュールをインポートします shark
これにより、コントローラーで定義したエクスポートされた関数を操作できるようになります。
const express = require('express');
const router = express.Router();
const shark = require('../controllers/sharks');
これで、を使用してルートを作成できます index
, create
、 と list
で定義した関数 sharks
コントローラファイル。 各ルートは適切なHTTPメソッドに関連付けられます。メインのサメ情報のランディングページをレンダリングしてサメのリストをユーザーに返す場合はGET、新しいサメのエントリを作成する場合はPOSTです。
...
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);
});
各ルートは、の関連機能を利用しています controllers/sharks.js
、このファイルの先頭にインポートすることで、そのモジュールにアクセスできるようにしたためです。
最後に、これらのルートをに添付してファイルを閉じます router
オブジェクトとそれらのエクスポート:
...
module.exports = router;
完成したファイルは次のようになります。
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;
編集が終了したら、ファイルを保存して閉じます。
これらのルートをアプリケーションにアクセスできるようにする最後のステップは、これらのルートをに追加することです。 app.js
. そのファイルをもう一度開きます。
- nano app.js
あなたの下に db
定数の場合、ルートに次のインポートを追加します。
...
const db = require('./db');
const sharks = require('./routes/sharks');
次に、置換 app.use
現在あなたをマウントする関数 router
次の行のオブジェクト。これにより、 sharks
ルーターモジュール:
...
app.use(express.static(path));
app.use('/sharks', sharks);
app.listen(port, function () {
console.log("Example app listening on port 8080!")
})
アプリケーションのルートを使用してインポートしているため、このファイルで以前に定義されたルートを削除できるようになりました。 sharks
ルーターモジュール。
あなたの最終バージョン 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!')
})
編集が終了したら、ファイルを保存して閉じます。
これで実行できます tree
プロジェクトの最終的な構造をもう一度確認するには、次のようにします。
- tree -I node_modules
プロジェクト構造は次のようになります。
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
すべてのアプリケーションコンポーネントが作成され、配置されたら、データベースにテストサメを追加する準備が整いました。
前提条件の初期サーバーセットアップチュートリアルに従った場合、ファイアウォールは現在SSHトラフィックのみを許可しているため、ファイアウォールを変更する必要があります。 ポートへのトラフィックを許可するには 8080
走る:
- sudo ufw allow 8080
アプリケーションを起動します。
- node app.js
次に、ブラウザを次の場所に移動します http://your_server_ip:8080
. 次のランディングページが表示されます。
Get SharkInfoボタンをクリックします。 サメの入力フォームが追加された次の情報ページが表示されます。
フォームに、選択したサメを追加します。 このデモンストレーションの目的で、追加します Megalodon Shark
Shark Name フィールドに移動し、 Ancient
Shark Character フィールドへ:
送信ボタンをクリックします。 このサメの情報が表示されたページが表示されます。
また、サメがコレクションに追加されたことを示す出力がコンソールに表示されます。
OutputExample app listening on port 8080!
{ name: 'Megalodon Shark', character: 'Ancient' }
新しいサメのエントリを作成する場合は、サメページに戻り、サメを追加するプロセスを繰り返します。
これで、ユーザーがお気に入りのサメに関する情報を追加できる、機能するサメ情報アプリケーションができました。
結論
このチュートリアルでは、MongoDBデータベースを統合し、MVCアーキテクチャパターンを使用してアプリケーションのロジックを書き直すことで、Nodeアプリケーションを構築しました。 このアプリケーションは、本格的なCRUDアプリケーションの出発点として適しています。
他のコンテキストでのMVCパターンに関するその他のリソースについては、Django開発シリーズまたはDjangoを使用して顧客情報を管理しUbuntu18.04でReactする最新のWebアプリケーションを構築する方法を参照してください。
MongoDBの操作の詳細については、MongoDBのチュートリアルのライブラリを参照してください。