ExpressJS-クイックガイド

ExpressJSは、Webサイト、Webアプリ、およびバックエンドを構築するための単純なAPIを提供するWebアプリケーションフレームワークです。ExpressJSを使用すると、低レベルのプロトコルやプロセスなどについて心配する必要はありません。

Expressとは何ですか?

Expressは、アプリケーションを構築するための最小限のインターフェースを提供します。アプリのビルドに必要なツールを提供します。で利用可能なモジュールが多数あるため、柔軟性がありますnpm、Expressに直接接続できます。

Expressはによって開発されました TJ Holowaychukそして、Node.js財団と多数のオープンソース貢献者によって維持されています。

なぜExpressなのか?

RailsやDjangoのような、アプリケーションを構築するための意見のある方法を持っている競合他社とは異なり、Expressには何かをするための「最良の方法」がありません。それは非常に柔軟でプラグイン可能です。

パグ

Pug(以前はJadeとして知られていました)は、HTMLテンプレートを作成するための簡潔な言語です。それ−

  • HTMLを生成します
  • 動的コードをサポート
  • 再利用性(DRY)をサポート

これは、Expressで使用される最も人気のあるテンプレート言語の1つです。

MongoDBとMongoose

MongoDBは、開発とスケーリングを容易にするために設計されたオープンソースのドキュメントデータベースです。このデータベースは、データの保存にも使用されます。

マングースはのクライアントAPIです node.js これにより、Expressアプリケーションからデータベースに簡単にアクセスできます。

この章では、ExpressFrameworkの開発と使用を開始する方法を学習します。まず、ノードとnpm(ノードパッケージマネージャー)がインストールされている必要があります。これらをまだ持っていない場合は、ノードのセットアップに移動して、ローカルシステムにノードをインストールします。ターミナルで次のコマンドを実行して、nodeとnpmがインストールされていることを確認します。

node --version
npm --version

次のような出力が得られるはずです。

v5.0.0
3.5.2

これでノードと npm 設定して、何を理解しましょう npm とその使用方法です。

ノードパッケージマネージャー(npm)

npmはノードのパッケージマネージャーです。npmレジストリは、Node.js、フロントエンドWebアプリ、モバイルアプリ、ロボット、ルーター、およびJavaScriptコミュニティの他の無数のニーズに対応するオープンソースコードのパッケージのパブリックコレクションです。npmを使用すると、これらすべてのパッケージにアクセスしてローカルにインストールできます。npmJSのnpmで利用可能なパッケージのリストを参照できます。

npmの使い方は?

npmを使用してパッケージをインストールするには、グローバルとローカルの2つの方法があります。

  • Globally−この方法は通常、開発ツールとCLIベースのパッケージをインストールするために使用されます。パッケージをグローバルにインストールするには、次のコードを使用します。

npm install -g <package-name>
  • Locally−この方法は通常、フレームワークとライブラリをインストールするために使用されます。ローカルにインストールされたパッケージは、インストールされているディレクトリ内でのみ使用できます。パッケージをローカルにインストールするには、上記と同じコマンドを使用します。-g 国旗。

npm install <package-name>

npmを使用してプロジェクトを作成するときはいつでも、 package.jsonファイルには、プロジェクトに関するすべての詳細が含まれています。npmを使用すると、このファイルを簡単に設定できます。開発プロジェクトを立ち上げましょう。

Step 1 − terminal / cmdを起動し、hello-worldという名前の新しいフォルダーを作成し、その中にcd(ディレクトリを作成)します。

Step 2 − npmを使用してpackage.jsonファイルを作成するには、次のコードを使用します。

npm init

以下の情報をお伺いします。

Enterキーを押し続け、「作成者名」フィールドに自分の名前を入力します。

Step 3− package.jsonファイルが設定されたので、Expressをさらにインストールします。Expressをインストールしてpackage.jsonファイルに追加するには、次のコマンドを使用します-

npm install --save express

Expressが正しくインストールされたことを確認するには、次のコードを実行します。

ls node_modules #(dir node_modules for windows)

Tip -save フラグは次のように置き換えることができます -S国旗。このフラグは、Expressが依存関係として追加されることを保証しますpackage.jsonファイル。これには利点があります。次にプロジェクトのすべての依存関係をインストールする必要があるときに、コマンドnpm installを実行するだけで、このファイル内の依存関係が検出され、インストールされます。

Expressフレームワークを使用して開発を開始するために必要なのはこれだけです。開発プロセスをはるかに簡単にするために、npm、nodemonからツールをインストールします。このツールは、ファイルに変更を加えるとすぐにサーバーを再起動します。そうしないと、ファイルを変更するたびにサーバーを手動で再起動する必要があります。nodemonをインストールするには、次のコマンドを使用します-

npm install -g nodemon

これで、Expressでの作業を開始できます。

開発をセットアップしました。今度は、Expressを使用して最初のアプリの開発を開始します。と呼ばれる新しいファイルを作成しますindex.js 次のように入力します。

var express = require('express');
var app = express();

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

app.listen(3000);

ファイルを保存し、ターミナルに移動して次のように入力します。

nodemon index.js

これにより、サーバーが起動します。このアプリをテストするには、ブラウザを開いてに移動しますhttp://localhost:3000 次のスクリーンショットのようにメッセージが表示されます。

アプリはどのように機能しますか?

最初の行はファイルにExpressをインポートし、変数Expressを介してアクセスできます。これを使用してアプリケーションを作成し、varappに割り当てます。

app.get(route、callback)

この関数は、次の場合に何をすべきかを指示します。 get指定されたルートでのリクエストが呼び出されます。コールバック関数には2つのパラメーターがあります。request(req) そして response(res)。リクエストobject(req) HTTPリクエストを表し、リクエストクエリ文字列、パラメータ、本文、HTTPヘッダーなどのプロパティがあります。同様に、responseオブジェクトは、ExpressアプリがHTTPリクエストを受信したときに送信するHTTPレスポンスを表します。

res.send()

この関数はオブジェクトを入力として受け取り、これを要求元のクライアントに送信します。ここでは、「HelloWorld!」という文字列を送信しています

app.listen(port、[host]、[backlog]、[callback]])

この関数は、指定されたホストとポートで接続をバインドしてリッスンします。ここで必要なパラメータはポートだけです。

S.No. 引数と説明
1

port

サーバーが着信要求を受け入れる必要があるポート番号。

2

host

ドメインの名前。アプリをクラウドにデプロイするときに設定する必要があります。

3

backlog

キューに入れられた保留中の接続の最大数。デフォルトは511です。

4

callback

サーバーがリクエストのリッスンを開始したときに呼び出される非同期関数。

Webフレームワークは、HTMLページ、スクリプト、画像などのリソースをさまざまなルートで提供します。

次の関数は、Expressアプリケーションでルートを定義するために使用されます-

app.method(パス、ハンドラー)

このメソッドは、HTTP動詞(get、set、put、delete)のいずれかに適用できます。リクエストタイプに関係なく実行される代替メソッドも存在します。

パスは、リクエストが実行されるルートです。

ハンドラーは、関連するルートで一致するリクエストタイプが見つかったときに実行されるコールバック関数です。例えば、

var express = require('express');
var app = express();

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

app.listen(3000);

アプリケーションを実行して localhost:3000/hello、サーバーはルートでgetリクエストを受信します "/hello"、Expressアプリは callback このルートに接続されて送信する関数 "Hello World!" 応答として。

同じルートで複数の異なる方法を使用することもできます。例えば、

var express = require('express');
var app = express();

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

app.post('/hello', function(req, res){
   res.send("You just called the post method at '/hello'!\n");
});

app.listen(3000);

このリクエストをテストするには、ターミナルを開き、cURLを使用して次のリクエストを実行します-

curl -X POST "http://localhost:3000/hello"

特別な方法、 allは、同じ関数を使用して特定のルートですべてのタイプのhttpメソッドを処理するためにExpressによって提供されます。この方法を使用するには、次のことを試してください。

app.all('/test', function(req, res){
   res.send("HTTP method doesn't have any effect on this route!");
});

このメソッドは通常、ミドルウェアの定義に使用されます。これについては、ミドルウェアの章で説明します。

ルーター

上記のようなルートを定義することは、維持するのが非常に面倒です。私たちのメインからルートを分離するにはindex.js ファイル、使用します Express.Router。と呼ばれる新しいファイルを作成しますthings.js 次のように入力します。

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

router.get('/', function(req, res){
   res.send('GET route on things.');
});
router.post('/', function(req, res){
   res.send('POST route on things.');
});

//export this router to use in our index.js
module.exports = router;

今、私たちの中でこのルーターを使用するには index.js、前に次のように入力します app.listen 関数呼び出し。

var express = require('Express');
var app = express();

var things = require('./things.js');

//both index.js and things.js should be in same directory
app.use('/things', things);

app.listen(3000);

ザ・ app.use ルート上の関数呼び出し '/things' を添付します thingsこのルートのルーター。これで、アプリが「/ things」で取得するリクエストはすべて、things.jsルーターによって処理されます。ザ・'/'things.jsのrouteは、実際には '/ things'のサブルートです。localhost:3000 / things /にアクセスすると、次の出力が表示されます。

ルーターは、関心の分離に非常に役立ち、コードの関連部分をまとめます。これらは、保守可能なコードの構築に役立ちます。エンティティに関連するルートを1つのファイルに定義し、上記の方法を使用してルートを含める必要があります。index.js ファイル。

HTTPメソッドはリクエストで提供され、クライアントがリクエストした操作を指定します。次の表に、最もよく使用されるHTTPメソッドを示します-

S.No. 方法と説明
1

GET

GETメソッドは、指定されたリソースの表現を要求します。GETを使用したリクエストは、データを取得するだけで、他の効果はありません。

2

POST

POSTメソッドは、サーバーがリクエストに含まれるデータをURIで識別されるリソースの新しいオブジェクト/エンティティとして受け入れることを要求します。

3

PUT

PUTメソッドは、URIで識別される既存のオブジェクトへの変更として、要求に含まれるデータをサーバーが受け入れることを要求します。存在しない場合は、PUTメソッドで作成する必要があります。

4

DELETE

DELETEメソッドは、サーバーが指定されたリソースを削除することを要求します。

これらは最も一般的なHTTPメソッドです。メソッドの詳細については、次のWebサイトをご覧ください。http://www.tutorialspoint.com/http/http_methods.htm。

これでルートを定義できますが、それらは静的または固定です。動的ルートを使用するには、さまざまなタイプのルートを提供する必要があります。動的ルートを使用すると、パラメーターを渡し、それに基づいて処理することができます。

これが動的ルートの例です-

var express = require('express');
var app = express();

app.get('/:id', function(req, res){
   res.send('The id you specified is ' + req.params.id);
});
app.listen(3000);

これをテストするには、 http://localhost:3000/123。以下の応答が表示されます。

URLの「123」を他のものに置き換えることができ、変更は応答に反映されます。上記のより複雑な例は次のとおりです。

var express = require('express');
var app = express();

app.get('/things/:name/:id', function(req, res) {
   res.send('id: ' + req.params.id + ' and name: ' + req.params.name);
});
app.listen(3000);

上記のコードをテストするには、 http://localhost:3000/things/tutorialspoint/12345

あなたは使用することができます req.paramsURLで渡したすべてのパラメータにアクセスするためのオブジェクト。上記の2つは異なるパスであることに注意してください。それらは決して重複しません。また、取得時にコードを実行したい場合'/things' 次に、それを個別に定義する必要があります。

パターン一致ルート

使用することもできます regexURLパラメータの一致を制限します。あなたが必要だと仮定しましょうid5桁の長い数字になります。次のルート定義を使用できます-

var express = require('express');
var app = express();

app.get('/things/:id([0-9]{5})', function(req, res){
   res.send('id: ' + req.params.id);
});

app.listen(3000);

これは only 5桁の長さのリクエストに一致します id。より複雑な正規表現を使用して、ルートを照合/検証できます。リクエストに一致するルートがない場合は、"Cannot GET <your-request-route>"応答としてのメッセージ。このメッセージは、この単純なルートを使用して404 notfoundページに置き換えられます-

var express = require('express');
var app = express();

//Other routes here
app.get('*', function(req, res){
   res.send('Sorry, this is an invalid URL.');
});
app.listen(3000);

Important − Expressはルートの最初から最後まで一致するため、これはすべてのルートの後に配置する必要があります。 index.js 必要な外部ルーターを含むファイル。

たとえば、上記と同じルートを定義した場合、有効なURLでリクエストすると、次の出力が表示されます。−

間違ったURLリクエストの場合、次の出力が表示されます。

ミドルウェア機能は、にアクセスできる機能です。 request object (req)response object (res)、およびアプリケーションの要求/応答サイクルの次のミドルウェア機能。これらの関数は変更に使用されますreq そして res リクエスト本文の解析、レスポンスヘッダーの追加などのタスク用のオブジェクト。

これが動作中のミドルウェア関数の簡単な例です-

var express = require('express');
var app = express();

//Simple request time logger
app.use(function(req, res, next){
   console.log("A new request received at " + Date.now());
   
   //This function call is very important. It tells that more processing is
   //required for the current request and is in the next middleware
   function/route handler.
   next();
});

app.listen(3000);

上記のミドルウェアは、サーバー上のすべての要求に対して呼び出されます。したがって、すべてのリクエストの後、コンソールに次のメッセージが表示されます-

A new request received at 1467267512545

特定のルート(およびそのすべてのサブルート)に制限するには、そのルートをの最初の引数として指定します。 app.use()。例えば、

var express = require('express');
var app = express();

//Middleware function to log request protocol
app.use('/things', function(req, res, next){
   console.log("A request for things received at " + Date.now());
   next();
});

// Route handler that sends the response
app.get('/things', function(req, res){
   res.send('Things');
});

app.listen(3000);

これで、「/ things」のサブルートを要求するたびに、時間がログに記録されます。

ミドルウェア呼び出しの順序

Expressのミドルウェアで最も重要なことの1つは、ミドルウェアがファイルに書き込まれる/含まれる順序です。ルートが一致することを前提として、それらが実行される順序も考慮する必要があります。

たとえば、次のコードスニペットでは、最初の関数が最初に実行され、次にルートハンドラー、次に終了関数が実行されます。この例は、ルートハンドラの前後でミドルウェアを使用する方法をまとめたものです。また、ルートハンドラーをミドルウェア自体として使用する方法についても説明します。

var express = require('express');
var app = express();

//First middleware before response is sent
app.use(function(req, res, next){
   console.log("Start");
   next();
});

//Route handler
app.get('/', function(req, res, next){
   res.send("Middle");
   next();
});

app.use('/', function(req, res){
   console.log('End');
});

app.listen(3000);

このコードを実行した後に「/」にアクセスすると、次のように応答を受け取ります。 Middle そして私たちのコンソールで-

Start
End

次の図は、ミドルウェアについて学んだことをまとめたものです。

独自のミドルウェアを作成する方法について説明したので、コミュニティで作成された最も一般的に使用されるミドルウェアのいくつかについて説明します。

サードパーティのミドルウェア

Express用のサードパーティミドルウェアのリストは、こちらから入手できます。以下は、最も一般的に使用されるミドルウェアの一部です。これらの使用/マウント方法も学習します-

ボディパーサー

これは、ペイロードがアタッチされているリクエストの本体を解析するために使用されます。ボディパーサーをマウントするには、を使用してインストールする必要がありますnpm install --body-parserを保存してマウントするには、index.jsに次の行を含めます-

var bodyParser = require('body-parser');

//To parse URL encoded data
app.use(bodyParser.urlencoded({ extended: false }))

//To parse json data
app.use(bodyParser.json())

body-parserで使用可能なすべてのオプションを表示するには、そのgithubページにアクセスしてください。

cookie-parser

Cookieヘッダーを解析し、Cookie名でキー設定されたオブジェクトをreq.cookiesに入力します。Cookieパーサーをマウントするには、npm install --save cookie-parserを使用してインストールする必要があります。マウントするには、index.jsに次の行を含めます。

var cookieParser = require('cookie-parser');
app.use(cookieParser())

エクスプレスセッション

指定されたオプションを使用してセッションミドルウェアを作成します。その使用法については、セッションセクションで説明します。

ExpressJSには他にも多くのサードパーティミドルウェアがあります。ただし、ここではいくつかの重要なものについてのみ説明しました。

Pugは、Express用のテンプレートエンジンです。テンプレートエンジンは、HTMLを使用したサーバーコードの乱雑さを取り除き、文字列を既存のHTMLテンプレートに乱暴に連結するために使用されます。Pugは非常に強力なテンプレートエンジンであり、次のようなさまざまな機能を備えています。filters, includes, inheritance, interpolation、など。これをカバーするための多くの根拠があります。

ExpressでPugを使用するには、Pugをインストールする必要があります。

npm install --save pug

Pugがインストールされたので、アプリのテンプレートエンジンとして設定します。君はdon'tそれを「必要とする」必要があります。次のコードをに追加しますindex.js ファイル。

app.set('view engine', 'pug');
app.set('views','./views');

次に、viewsという新しいディレクトリを作成します。その中に、というファイルを作成しますfirst_view.pug、に次のデータを入力します。

doctype html
html
   head
      title = "Hello Pug"
   body
      p.greetings#people Hello World!

このページを実行するには、アプリに次のルートを追加します-

app.get('/first_template', function(req, res){
   res.render('first_view');
});

次のように出力が得られます- Hello World!Pugは、この非常に単純な外観のマークアップをhtmlに変換します。タグの終了を追跡する必要はありません。classキーワードとidキーワードを使用する必要はなく、「。」を使用します。そして'#'それらを定義します。上記のコードは最初に-に変換されます

<!DOCTYPE html>
<html>
   <head>
      <title>Hello Pug</title>
   </head>
   
   <body>
      <p class = "greetings" id = "people">Hello World!</p>
   </body>
</html>

Pugは、HTMLマークアップを単純化する以上のことを実行できます。

パグの重要な機能

ここで、Pugのいくつかの重要な機能について説明します。

シンプルなタグ

タグは、インデントに従ってネストされます。上記の例のように、<title> 内でインデントされました <head>タグなので、中にありました。しかし<body> タグは同じインデントにあったので、それはの兄弟でした <head> 鬼ごっこ。

タグを閉じる必要はありません。Pugが同じまたは外側のインデントレベルで次のタグに遭遇するとすぐに、タグを閉じます。

タグ内にテキストを配置するには、3つの方法があります-

  • Space seperated

h1 Welcome to Pug
  • Piped text

div
   | To insert multiline text, 
   | You can use the pipe operator.
  • Block of text

div.
   But that gets tedious if you have a lot of text.
   You can use "." at the end of tag to denote block of text.
   To put tags inside this block, simply enter tag in a new line and 
   indent it accordingly.

コメント

Pugはと同じ構文を使用します JavaScript(//)コメントを作成するため。これらのコメントはhtmlコメント(<!-comment->)に変換されます。例えば、

//This is a Pug comment

このコメントは次のように変換されます。

<!--This is a Pug comment-->

属性

属性を定義するには、括弧内にコンマで区切られた属性のリストを使用します。クラス属性とID属性には特別な表現があります。次のコード行では、特定のhtmlタグの属性、クラス、およびIDの定義について説明します。

div.container.column.main#division(width = "100", height = "100")

このコード行は、次のように変換されます。−

<div class = "container column main" id = "division" width = "100" height = "100"></div>

テンプレートへの値の受け渡し

Pugテンプレートをレンダリングするとき、実際にはルートハンドラーから値を渡すことができ、それをテンプレートで使用できます。次のように新しいルートハンドラを作成します。

var express = require('express');
var app = express();

app.get('/dynamic_view', function(req, res){
   res.render('dynamic', {
      name: "TutorialsPoint", 
      url:"http://www.tutorialspoint.com"
   });
});

app.listen(3000);

そして、viewsディレクトリに新しいビューファイルを作成します。 dynamic.pug、次のコードで-

html
   head
      title=name
   body
      h1=name
      a(href = url) URL

ブラウザでlocalhost:3000 / dynamic_viewを開きます。次の出力が得られるはずです-

これらの渡された変数をテキスト内で使用することもできます。タグのテキストの間に渡された変数を挿入するには、#{variableName}構文。たとえば、上記の例で、TutorialsPointからGreetingsを配置したい場合は、次のようにすることができます。

html
   head
      title = name
   body
      h1 Greetings from #{name}
      a(href = url) URL

値を使用するこの方法は、 interpolation。上記のコードは、次の出力を表示します。−

条件付き

条件文とループ構造も使用できます。

次のことを考慮してください-

ユーザーがログインしている場合、ページは表示されます "Hi, User" そうでない場合は、 "Login/Sign Up"リンク。これを実現するために、次のような単純なテンプレートを定義できます。

html
   head
      title Simple template
   body
      if(user)
         h1 Hi, #{user.name}
      else
         a(href = "/sign_up") Sign Up

ルートを使用してこれをレンダリングすると、次のプログラムのようにオブジェクトを渡すことができます-

res.render('/dynamic',{
   user: {name: "Ayush", age: "20"}
});

あなたはメッセージを受け取ります- Hi, Ayush。ただし、オブジェクトを渡さない場合、またはユーザーキーなしで渡す場合は、サインアップリンクが表示されます。

インクルードとコンポーネント

Pugは、Webページのコンポーネントを作成するための非常に直感的な方法を提供します。たとえば、ニュースWebサイトを表示した場合、ロゴとカテゴリを含むヘッダーは常に固定されています。作成するすべてのビューにそれをコピーする代わりに、include特徴。次の例は、この機能の使用方法を示しています-

次のコードで3つのビューを作成します-

HEADER.PUG

div.header.
   I'm the header for this website.

CONTENT.PUG

html
   head
      title Simple template
   body
      include ./header.pug
      h3 I'm the main content
      include ./footer.pug

FOOTER.PUG

div.footer.
   I'm the footer for this website.

このためのルートを次のように作成します-

var express = require('express');
var app = express();

app.get('/components', function(req, res){
    res.render('content');
});

app.listen(3000);

localhost:3000 / componentsに移動すると、次の出力が表示されます-

include 平文、css、JavaScriptを含めるためにも使用できます。

パグにはもっとたくさんの機能があります。ただし、これらはこのチュートリアルの範囲外です。PugでPugをさらに探索できます。

静的ファイルは、クライアントがサーバーからそのままダウンロードするファイルです。新しいディレクトリを作成し、public。Expressでは、デフォルトでは静的ファイルを提供できません。以下の組み込みミドルウェアを使用して有効にする必要があります。

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

Note − Expressは静的ディレクトリに関連するファイルを検索するため、静的ディレクトリの名前はURLの一部ではありません。

ルートルートがパブリックディレクトリに設定されているため、ロードするすべての静的ファイルはパブリックをルートと見なします。これが正常に機能していることをテストするには、新しい画像ファイルを追加しますpublic dirとその名前を「testimage.jpg"。ビューで、新しいビューを作成し、次のようにこのファイルを含めます-

html
   head
   body
      h3 Testing static file serving:
      img(src = "/testimage.jpg", alt = "Testing Image

次の出力が得られるはずです-

複数の静的ディレクトリ

次のプログラムを使用して、複数の静的アセットディレクトリを設定することもできます-

var express = require('express');
var app = express();

app.use(express.static('public'));
app.use(express.static('images'));

app.listen(3000);

仮想パスプレフィックス

静的ファイルを提供するためのパスプレフィックスを提供することもできます。たとえば、次のようなパスプレフィックスを提供する場合'/static'、次のコードをに含める必要があります index.js ファイル-

var express = require('express');
var app = express();

app.use('/static', express.static('public'));

app.listen(3000);

これで、パブリックディレクトリにあるmain.jsというスクリプトファイルなどのファイルを含める必要がある場合は、次のスクリプトタグを使用します。

<script src = "/static/main.js" />

この手法は、静的ファイルとして複数のディレクトリを提供する場合に役立ちます。これらのプレフィックスは、複数のディレクトリを区別するのに役立ちます。

フォームはウェブの不可欠な部分です。私たちが訪問するほとんどすべてのウェブサイトは、私たちのためにいくつかの情報を送信または取得するフォームを提供しています。フォームの使用を開始するには、最初にbody-parser(JSONおよびURLエンコードされたデータを解析するため)とmulter(マルチパート/フォームデータを解析するため)ミドルウェアをインストールします。

body-parsermulterをインストールするには、ターミナルに移動して-を使用します。

npm install --save body-parser multer

あなたの index.js 次のコードのファイルの内容-

var express = require('express');
var bodyParser = require('body-parser');
var multer = require('multer');
var upload = multer();
var app = express();

app.get('/', function(req, res){
   res.render('form');
});

app.set('view engine', 'pug');
app.set('views', './views');

// for parsing application/json
app.use(bodyParser.json()); 

// for parsing application/xwww-
app.use(bodyParser.urlencoded({ extended: true })); 
//form-urlencoded

// for parsing multipart/form-data
app.use(upload.array()); 
app.use(express.static('public'));

app.post('/', function(req, res){
   console.log(req.body);
   res.send("recieved your request!");
});
app.listen(3000);

ボディパーサーとマルターをインポートした後、 body-parser jsonおよびx-www-form-urlencodedヘッダーリクエストを解析するために使用します multer multipart / form-dataを解析するため。

これをテストするためのhtmlフォームを作成しましょう。と呼ばれる新しいビューを作成しますform.pug 次のコードで-

html
html
   head
      title Form Tester
   body
      form(action = "/", method = "POST")
         div
            label(for = "say") Say:
            input(name = "say" value = "Hi")
         br
         div
            label(for = "to") To:
            input(name = "to" value = "Express forms")
         br
         button(type = "submit") Send my greetings

以下を使用してサーバーを実行します。

nodemon index.js

次に、localhost:3000 /に移動し、必要に応じてフォームに入力して送信します。次の応答が表示されます-

コンソールを見てください。次のスクリーンショットのように、リクエストの本文がJavaScriptオブジェクトとして表示されます-

ザ・ req.bodyオブジェクトには、解析されたリクエスト本文が含まれます。そのオブジェクトのフィールドを使用するには、通常のJSオブジェクトと同じように使用します。

これは、リクエストを送信するための最も推奨される方法です。他にも多くの方法がありますが、Expressアプリがこれらすべてのリクエストを同じ方法で処理するため、ここで説明することは関係ありません。リクエストを行うさまざまな方法の詳細については、このページをご覧ください。

私たちはリクエストを受け取り続けますが、結局どこにも保存されません。データを保存するためのデータベースが必要です。このために、と呼ばれるNoSQLデータベースを利用しますMongoDB

Mongoをインストールして読むには、このリンクをたどってください。

ExpressでMongoを使用するには、ノード用のクライアントAPIが必要です。複数のオプションがありますが、このチュートリアルでは、マングースに固執します。マングースはdocument ModelingMongoDBのノードで。ドキュメントモデリングでは、Model (のように class ドキュメント指向プログラミングで)、そして私たちは documents このモデルを使用して(私たちが作成するように) documents of a classOOPで)。すべての処理はこれらの「ドキュメント」に対して実行され、最後にこれらのドキュメントをデータベースに書き込みます。

マングースの設定

Mongoをインストールしたので、他のノードパッケージをインストールしたのと同じ方法でMongooseをインストールしましょう-

npm install --save mongoose

mongooseの使用を開始する前に、Mongoシェルを使用してデータベースを作成する必要があります。新しいデータベースを作成するには、ターミナルを開いて「mongo」と入力します。Mongoシェルが起動します。次のコードを入力してください-

use my_db

新しいデータベースが作成されます。mongoシェルを開くと、デフォルトで「test」dbになり、上記と同じコマンドを使用してデータベースに変更する必要があります。

マングースを使用するには、マングースが必要になります index.js ファイルを作成してからに接続します mongodb で実行されているサービス mongodb://localhost

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');

これでアプリがデータベースに接続されました。新しいモデルを作成しましょう。このモデルは、データベースのコレクションとして機能します。新しいモデルを作成するには、ルートを定義する前に、次のコードを使用します-

var personSchema = mongoose.Schema({
   name: String,
   age: Number,
   nationality: String
});
var Person = mongoose.model("Person", personSchema);

上記のコードは、人のスキーマを定義し、Mongooseモードを作成するために使用されます Person

ドキュメントの保存

次に、新しいhtmlフォームを作成します。このフォームは、人の詳細を取得してデータベースに保存するのに役立ちます。フォームを作成するには、という新しいビューファイルを作成します。person.pug 次の内容のviewsディレクトリ内-

html
head
   title Person
   body
      form(action = "/person", method = "POST")
      div
         label(for = "name") Name: 
         input(name = "name")
      br
      div
         label(for = "age") Age: 
         input(name = "age")
      br
      div
         label(for = "nationality") Nationality: 
         input(name = "nationality")
      br
      button(type = "submit") Create new person

また、 new get routeindex.js このドキュメントをレンダリングするには-

app.get('/person', function(req, res){
   res.render('person');
});

localhost:3000/person"フォームが正しい出力を表示しているかどうかを確認します。これはUIであり、まだ機能していないことに注意してください。次のスクリーンショットは、フォームの表示方法を示しています-

ここで、ポストルートハンドラーをで定義します。 '/person' このリクエストを処理します

app.post('/person', function(req, res){
   var personInfo = req.body; //Get the parsed information
   
   if(!personInfo.name || !personInfo.age || !personInfo.nationality){
      res.render('show_message', {
         message: "Sorry, you provided worng info", type: "error"});
   } else {
      var newPerson = new Person({
         name: personInfo.name,
         age: personInfo.age,
         nationality: personInfo.nationality
      });
		
      newPerson.save(function(err, Person){
         if(err)
            res.render('show_message', {message: "Database error", type: "error"});
         else
            res.render('show_message', {
               message: "New person added", type: "success", person: personInfo});
      });
   }
});

上記のコードでは、空のフィールドを受け取った場合、またはフィールドを受け取らなかった場合、エラー応答を送信します。しかし、整形式のドキュメントを受け取った場合は、newPerson Personモデルからドキュメントを作成し、を使用してDBに保存します。 newPerson.save()関数。これはMongooseで定義されており、引数としてコールバックを受け入れます。このコールバックには、エラーと応答の2つの引数があります。これらの引数は、show_message 見る。

このルートからの応答を表示するには、 show_message見る。次のコードで新しいビューを作成します-

html
   head
      title Person
   body
      if(type == "error")
         h3(style = "color:red") #{message}
      else
         h3 New person, 
            name: #{person.name}, 
            age: #{person.age} and 
            nationality: #{person.nationality} added!

正常に送信すると、次の応答が返されます。 form(show_message.pug)

これで、作成するインターフェイスができました persons

ドキュメントの取得

Mongooseは、ドキュメントを取得するための多くの機能を提供します。そのうちの3つに焦点を当てます。これらの関数はすべて、最後のパラメーターとしてコールバックも受け取ります。save関数と同様に、引数はエラーと応答です。3つの機能は次のとおりです-

Model.find(条件、コールバック)

この関数は、条件オブジェクトのフィールドに一致するすべてのドキュメントを検索します。Mongoで使用されているのと同じ演算子がmongooseでも機能します。例えば、

Person.find(function(err, response){
   console.log(response);
});

これにより、個人のコレクションからすべてのドキュメントがフェッチされます。

Person.find({name: "Ayush", age: 20}, 
   function(err, response){
      console.log(response);
});

これにより、フィールド名が「Ayush」で年齢が20のすべてのドキュメントがフェッチされます。

また、必要な予測、つまり必要なフィールドを提供することもできます。たとえば、names その人々の nationality「インド」で、使用します-

Person.find({nationality: "Indian"}, "name", function(err, response){
   console.log(response);
});

Model.findOne(条件、コールバック)

この関数は、常に単一の最も関連性の高いドキュメントをフェッチします。それはとまったく同じ引数を持っていますModel.find()

Model.findById(id、callback)

この関数は、 _id(mongoで定義)最初の引数、オプションの射影文字列、および応答を処理するためのコールバック。例えば、

Person.findById("507f1f77bcf86cd799439011", function(err, response){
   console.log(response);
});

すべての人の記録を表示するルートを作成しましょう-

var express = require('express');
var app = express();

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');

var personSchema = mongoose.Schema({
   name: String,
   age: Number,
   nationality: String
});

var Person = mongoose.model("Person", personSchema);

app.get('/people', function(req, res){
   Person.find(function(err, response){
      res.json(response);
   });
});

app.listen(3000);

ドキュメントの更新

マングースは、ドキュメントを更新するための3つの機能を提供します。機能は以下のとおりです。

Model.update(条件、更新、コールバック)

この関数は、条件を受け取り、入力としてオブジェクトを更新し、コレクション内の条件に一致するすべてのドキュメントに変更を適用します。たとえば、次のコードは、すべての個人文書の国籍「アメリカ人」を更新します-

Person.update({age: 25}, {nationality: "American"}, function(err, response){
   console.log(response);
});

Model.findOneAndUpdate(条件、更新、コールバック)

クエリに基づいて1つのドキュメントを検索し、2番目の引数に従ってそれを更新します。また、最後の引数としてコールバックを取ります。関数を理解するために次の例を実行してみましょう

Person.findOneAndUpdate({name: "Ayush"}, {age: 40}, function(err, response) {
   console.log(response);
});

Model.findByIdAndUpdate(id、updates、callback)

この関数は、IDで識別される単一のドキュメントを更新します。例えば、

Person.findByIdAndUpdate("507f1f77bcf86cd799439011", {name: "James"}, 
   function(err, response){
      console.log(response);
});

人々を更新するためのルートを作成しましょう。これはPUT パラメータとしてIDを使用し、ペイロードに詳細を指定してルーティングします。

var express = require('express');
var app = express();

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');

var personSchema = mongoose.Schema({
   name: String,
   age: Number,
   nationality: String
});

var Person = mongoose.model("Person", personSchema);

app.put('/people/:id', function(req, res){
   Person.findByIdAndUpdate(req.params.id, req.body, function(err, response){
      if(err) res.json({message: "Error in updating person with id " + req.params.id});
      res.json(response);
   });
});

app.listen(3000);

このルートをテストするには、ターミナルに次のように入力します(IDを作成したIDに置き換えます) people)−

curl -X PUT --data "name = James&age = 20&nationality = American
"http://localhost:3000/people/507f1f77bcf86cd799439011

これにより、ルートで提供されたIDに関連付けられたドキュメントが上記の詳細で更新されます。

ドキュメントの削除

カバーしました Create, Read そして Update、今度はマングースをどのように使用できるかを見ていきます Deleteドキュメント。ここには、更新とまったく同じように3つの関数があります。

Model.remove(condition、[callback])

この関数は、条件オブジェクトを入力として受け取り、条件に一致するすべてのドキュメントを削除します。たとえば、20歳のすべての人を削除する必要がある場合は、次の構文を使用します-

Person.remove({age:20});

Model.findOneAndRemove(condition、[callback])

この関数は、 single、条件オブジェクトに応じた最も関連性の高いドキュメント。同じことを理解するために、次のコードを実行してみましょう。

Person.findOneAndRemove({name: "Ayush"});

Model.findByIdAndRemove(id、[コールバック])

この関数は、IDで識別される単一のドキュメントを削除します。例えば、

Person.findByIdAndRemove("507f1f77bcf86cd799439011");

データベースから人を削除するルートを作成しましょう。

var express = require('express');
var app = express();

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');

var personSchema = mongoose.Schema({
   name: String,
   age: Number,
   nationality: String
});

var Person = mongoose.model("Person", personSchema);

app.delete('/people/:id', function(req, res){
   Person.findByIdAndRemove(req.params.id, function(err, response){
      if(err) res.json({message: "Error in deleting record id " + req.params.id});
      else res.json({message: "Person with id " + req.params.id + " removed."});
   });
});

app.listen(3000);

出力を確認するには、次のcurlコマンドを使用します-

curl -X DELETE http://localhost:3000/people/507f1f77bcf86cd799439011

これにより、指定されたIDを持つ人が削除され、次のメッセージが生成されます-

{message: "Person with id 507f1f77bcf86cd799439011 removed."}

これで、MongoDB、Mongoose、Expressを使用して簡単なCRUDアプリケーションを作成する方法をまとめました。マングースをさらに詳しく調べるには、APIドキュメントをお読みください。

Cookieは、サーバーリクエストでクライアントに送信され、クライアント側に保存される単純な小さなファイル/データです。ユーザーがウェブサイトを再度読み込むたびに、このCookieはリクエストとともに送信されます。これは、ユーザーのアクションを追跡するのに役立ちます。

以下は、HTTPCookieのさまざまな用途です-

  • セッション管理
  • パーソナライズ(レコメンデーションシステム)
  • ユーザー追跡

ExpressでCookieを使用するには、Cookieパーサーミドルウェアが必要です。インストールするには、次のコードを使用します-

npm install --save cookie-parser

ExpressでCookieを使用するには、 cookie-parser。cookie-parserは、クライアント要求オブジェクトに添付されたCookie解析するミドルウェアです。それを使用するには、私たちの中でそれを必要としますindex.jsファイル; これは、他のミドルウェアを使用するのと同じ方法で使用できます。ここでは、次のコードを使用します。

var cookieParser = require('cookie-parser');
app.use(cookieParser());

cookie-parserはCookieヘッダーを解析し、データを入力します req.cookiesCookie名でキー設定されたオブジェクトを使用します。新しいCookieを設定するには、Expressアプリで次のような新しいルートを定義します。

var express = require('express');
var app = express();

app.get('/', function(req, res){
   res.cookie('name', 'express').send('cookie set'); //Sets name = express
});

app.listen(3000);

Cookieが設定されているかどうかを確認するには、ブラウザに移動してコンソールを起動し、「-」と入力します。

console.log(document.cookie);

次のような出力が得られます(ブラウザの拡張機能が原因で、Cookieがさらに設定されている可能性があります)-

"name = express"

また、ブラウザはサーバーにクエリを実行するたびにCookieを送り返します。サーバーからのCookieを表示するには、ルート内のサーバーコンソールで、そのルートに次のコードを追加します。

console.log('Cookies: ', req.cookies);

次回このルートにリクエストを送信すると、次の出力が表示されます。

Cookies: { name: 'express' }

有効期限付きのCookieの追加

有効期限が切れるCookieを追加できます。有効期限が切れるCookieを追加するには、プロパティ「expire」が有効期限が切れる時間に設定されたオブジェクトを渡すだけです。例えば、

//Expires after 360000 ms from the time it is set.
res.cookie(name, 'value', {expire: 360000 + Date.now()});

有効期限を設定する別の方法は、 'maxAge'プロパティ。このプロパティを使用すると、絶対時間ではなく相対時間を提供できます。以下は、この方法の例です。

//This cookie also expires after 360000 ms from the time it is set.
res.cookie(name, 'value', {maxAge: 360000});

既存のCookieの削除

Cookieを削除するには、clearCookie関数を使用します。たとえば、という名前のCookieをクリアする必要がある場合foo、次のコードを使用します。

var express = require('express');
var app = express();

app.get('/clear_cookie_foo', function(req, res){
   res.clearCookie('foo');
   res.send('cookie foo cleared');
});

app.listen(3000);

次の章では、Cookieを使用してセッションを管理する方法を説明します。

HTTPはステートレスです。リクエストを他のリクエストに関連付けるには、HTTPリクエスト間でユーザーデータを保存する方法が必要です。CookieとURLパラメータはどちらも、クライアントとサーバー間でデータを転送するための適切な方法です。しかし、それらは読み取り可能であり、クライアント側でもあります。セッションはまさにこの問題を解決します。クライアントにIDを割り当てると、そのIDを使用してそれ以降のすべての要求が行われます。クライアントに関連付けられた情報は、このIDにリンクされたサーバーに保存されます。

Express-sessionが必要になるので、次のコードを使用してインストールします。

npm install --save express-session

入れます session そして cookie-parserミドルウェアが設置されています。この例では、セッションを保存するためのデフォルトのストア、つまりMemoryStoreを使用します。これを実稼働環境で使用しないでください。セッションミドルウェアは、セッションの作成、セッションCookieの設定、セッションオブジェクトの作成など、すべてを処理します。req オブジェクト。

同じクライアントから再度リクエストを行うと、セッション情報が保存されます(サーバーが再起動されていない場合)。セッションオブジェクトにさらにプロパティを追加できます。次の例では、クライアントのビューカウンターを作成します。

var express = require('express');
var cookieParser = require('cookie-parser');
var session = require('express-session');

var app = express();

app.use(cookieParser());
app.use(session({secret: "Shh, its a secret!"}));

app.get('/', function(req, res){
   if(req.session.page_views){
      req.session.page_views++;
      res.send("You visited this page " + req.session.page_views + " times");
   } else {
      req.session.page_views = 1;
      res.send("Welcome to this page for the first time!");
   }
});
app.listen(3000);

上記のコードは、ユーザーがサイトにアクセスすると、ユーザーの新しいセッションを作成し、Cookieを割り当てます。次回ユーザーが来ると、Cookieがチェックされ、page_view セッション変数はそれに応じて更新されます。

アプリを実行して localhost:3000、次の出力が表示されます。

ページに再度アクセスすると、ページカウンターが増加します。次のスクリーンショットのページは42回更新されました。

認証は、提供された資格情報が、ローカルオペレーティングシステムまたは認証サーバー内の許可されたユーザーの情報のデータベースにファイルされている資格情報と比較されるプロセスです。資格情報が一致する場合、プロセスは完了し、ユーザーにはアクセスの許可が付与されます。

認証システムを作成するには、サインアップページとユーザーパスワードストアを作成する必要があります。次のコードは、私たちのアカウントを作成し、それをメモリに保存します。これはデモを目的としたものです。ユーザー情報の保存には、常に永続ストレージ(データベースまたはファイル)を使用することをお勧めします。

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var multer = require('multer');
var upload = multer(); 
var session = require('express-session');
var cookieParser = require('cookie-parser');

app.set('view engine', 'pug');
app.set('views','./views');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true })); 
app.use(upload.array());
app.use(cookieParser());
app.use(session({secret: "Your secret key"}));

var Users = [];

app.get('/signup', function(req, res){
   res.render('signup');
});

app.post('/signup', function(req, res){
   if(!req.body.id || !req.body.password){
      res.status("400");
      res.send("Invalid details!");
   } else {
      Users.filter(function(user){
         if(user.id === req.body.id){
            res.render('signup', {
               message: "User Already Exists! Login or choose another user id"});
         }
      });
      var newUser = {id: req.body.id, password: req.body.password};
      Users.push(newUser);
      req.session.user = newUser;
      res.redirect('/protected_page');
   }
});

app.listen(3000);

サインアップフォームで、という新しいビューを作成します signup.jade.

SIGNUP.JADE

html
   head
      title Signup
   body
      if(message)
         h4 #{message}
         form(action = "/signup" method = "POST")
         input(name = "id" type = "text" required placeholder = "User ID")
         input(name = "password" type = "password" required placeholder = "Password")
         button(type = "Submit") Sign me up!

localhost:3000 / signupにアクセスして、このページが読み込まれるかどうかを確認してください。

両方のフィールドに必須の属性を設定したため、HTML5対応のブラウザーでは、IDとパスワードの両方を指定するまでこのフォームを送信できません。ユーザーIDまたはパスワードなしでcurlリクエストを使用して登録しようとすると、エラーが表示されます。と呼ばれる新しいファイルを作成しますprotected_page.pug 次の内容のビューで-

html
   head
      title Protected page
   body
      div Hey #{id}, How are you doing today?
      div Want to log out?
      div Logout

このページは、ユーザーがサインアップまたはログインしたばかりの場合にのみ表示されます。ここで、そのルートと、ログインおよびログアウトするルートを定義しましょう。

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var multer = require('multer');
var upload = multer(); 
var session = require('express-session');
var cookieParser = require('cookie-parser');

app.set('view engine', 'pug');
app.set('views','./views');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true })); 
app.use(upload.array());
app.use(cookieParser());
app.use(session({secret: "Your secret key"}));

var Users = [];

app.get('/signup', function(req, res){
   res.render('signup');
});

app.post('/signup', function(req, res){
   if(!req.body.id || !req.body.password){
      res.status("400");
      res.send("Invalid details!");
   } else {
      Users.filter(function(user){
         if(user.id === req.body.id){
            res.render('signup', {
               message: "User Already Exists! Login or choose another user id"});
         }
      });
      var newUser = {id: req.body.id, password: req.body.password};
      Users.push(newUser);
      req.session.user = newUser;
      res.redirect('/protected_page');
   }
});
function checkSignIn(req, res){
   if(req.session.user){
      next();     //If session exists, proceed to page
   } else {
      var err = new Error("Not logged in!");
      console.log(req.session.user);
      next(err);  //Error, trying to access unauthorized page!
   }
}
app.get('/protected_page', checkSignIn, function(req, res){
   res.render('protected_page', {id: req.session.user.id})
});

app.get('/login', function(req, res){
   res.render('login');
});

app.post('/login', function(req, res){
   console.log(Users);
   if(!req.body.id || !req.body.password){
      res.render('login', {message: "Please enter both id and password"});
   } else {
      Users.filter(function(user){
         if(user.id === req.body.id && user.password === req.body.password){
            req.session.user = user;
            res.redirect('/protected_page');
         }
      });
      res.render('login', {message: "Invalid credentials!"});
   }
});

app.get('/logout', function(req, res){
   req.session.destroy(function(){
      console.log("user logged out.")
   });
   res.redirect('/login');
});

app.use('/protected_page', function(err, req, res, next){
console.log(err);
   //User should be authenticated! Redirect him to log in.
   res.redirect('/login');
});

app.listen(3000);

ユーザーがサインインしているかどうかを確認するミドルウェア関数checkSignInを作成しました。protected_pageこの関数を使用します。ユーザーをログアウトするために、セッションを破棄します。

ログインページを作成しましょう。ビューに次の名前を付けますlogin.pug 内容を入力してください-

html
   head
      title Signup
   body
      if(message)
         h4 #{message}
         form(action = "/login" method = "POST")
         input(name = "id" type = "text" required placeholder = "User ID")
         input(name = "password" type = "password" required placeholder = "Password")
         button(type = "Submit") Log in

これで、簡単な認証アプリケーションが完成しました。アプリケーションをテストしてみましょう。nodemon index.jsを使用してアプリを実行し、localhost:3000 / signupに進みます。

ユーザー名とパスワードを入力し、[サインアップ]をクリックします。にリダイレクトされますprotected_page 詳細が有効/一意である場合-

次に、アプリからログアウトします。これにより、ログインページにリダイレクトされます-

このルートは、認証されていない人がアクセスしようとすると、ログインページにリダイレクトされるように保護されています。これはすべて、基本的なユーザー認証に関するものでした。永続的なセッションシステムを使用し、パスワードの転送にはハッシュを使用することを常にお勧めします。JSONトークンを利用して、ユーザーを認証するためのより良い方法があります。

APIは、モバイルアプリケーション、シングルページアプリケーションを作成し、AJAX呼び出しを使用して、クライアントにデータを提供するために常に必要です。これらのAPIとエンドポイントを構造化して名前を付ける方法の一般的なアーキテクチャスタイルは、REST(Representational Transfer State)HTTP 1.1RESTの原則を念頭に置いて設計されました。RESTはによって導入されましたRoy Fielding 2000年に彼のペーパーフィールディング論文で。

RESTful URIとメソッドは、リクエストを処理するために必要なほぼすべての情報を提供します。以下の表は、さまざまな動詞の使用方法とURIの命名方法をまとめたものです。最後に、moviesAPIを作成します。それがどのように構成されるかについて議論しましょう。

方法 URI 詳細 関数
取得する /映画 安全で、追跡可能 すべての映画とその詳細のリストを取得します
取得する / movies / 1234 安全で、追跡可能 映画ID1234の詳細を取得します
役職 /映画 該当なし 提供された詳細を使用して新しいムービーを作成します。応答には、この新しく作成されたリソースのURIが含まれています。
プット / movies / 1234 べき等 ムービーID1234を変更します(まだ存在しない場合は作成します)。応答には、この新しく作成されたリソースのURIが含まれています。
削除 / movies / 1234 べき等 ムービーID1234が存在する場合は、削除する必要があります。応答には、要求のステータスが含まれている必要があります。
削除または配置 /映画 無効 無効にする必要があります。 DELETE そして PUT 作業しているリソースを指定する必要があります。

ExpressでこのAPIを作成しましょう。JavaScriptでの操作が簡単で、他にも利点があるため、トランスポートデータ形式としてJSONを使用します。あなたのindex.js とファイル movies.js 次のプログラムのようにファイルします。

index.js

var express = require('express');
var bodyParser = require('body-parser');
var multer = require('multer');
var upload = multer();

var app = express();

app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(upload.array());

//Require the Router we defined in movies.js
var movies = require('./movies.js');

//Use the Router on the sub route /movies
app.use('/movies', movies);

app.listen(3000);

アプリケーションのセットアップが完了したので、APIの作成に集中しましょう。

まず、movies.jsファイルを設定します。映画の保存にデータベースを使用していませんが、メモリに保存しています。そのため、サーバーが再起動するたびに、追加されたムービーは消えます。これは、データベースまたはファイルを使用して(ノードfsモジュールを使用して)簡単に模倣できます。

Expressをインポートしたら、ルーターを作成し、module.exports −を使用してエクスポートします。

var express = require('express');
var router = express.Router();
var movies = [
   {id: 101, name: "Fight Club", year: 1999, rating: 8.1},
   {id: 102, name: "Inception", year: 2010, rating: 8.7},
   {id: 103, name: "The Dark Knight", year: 2008, rating: 9},
   {id: 104, name: "12 Angry Men", year: 1957, rating: 8.9}
];

//Routes will go here
module.exports = router;

ルートを取得

すべての映画を取得するためのGETルートを定義しましょう-

router.get('/', function(req, res){
   res.json(movies);
});

これが正常に機能しているかどうかをテストするには、アプリを実行し、ターミナルを開いて「-」と入力します。

curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET 
localhost:3000/movies

次の応答が表示されます-

[{"id":101,"name":"Fight Club","year":1999,"rating":8.1},
{"id":102,"name":"Inception","year":2010,"rating":8.7},
{"id":103,"name":"The Dark Knight","year":2008,"rating":9},
{"id":104,"name":"12 Angry Men","year":1957,"rating":8.9}]

すべての映画を入手するルートがあります。IDで特定の映画を取得するルートを作成しましょう。

router.get('/:id([0-9]{3,})', function(req, res){
   var currMovie = movies.filter(function(movie){
      if(movie.id == req.params.id){
         return true;
      }
   });
   if(currMovie.length == 1){
      res.json(currMovie[0])
   } else {
      res.status(404);//Set status to 404 as movie was not found
      res.json({message: "Not Found"});
   }
});

これにより、指定したIDに従って映画が取得されます。出力を確認するには、端末で次のコマンドを使用します-

curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET 
localhost:3000/movies/101

次の応答が返されます-

{"id":101,"name":"Fight Club","year":1999,"rating":8.1}

無効なルートにアクセスすると、 cannot GET error 一方、IDが存在しない有効なルートにアクセスすると、404エラーが発生します。

GETルートが完了しました。次に、 POST ルート。

POSTルート

次のルートを使用して、 POSTed データ-

router.post('/', function(req, res){
   //Check if all fields are provided and are valid:
   if(!req.body.name ||
      !req.body.year.toString().match(/^[0-9]{4}$/g) || !req.body.rating.toString().match(/^[0-9]\.[0-9]$/g)){
      
      res.status(400);
      res.json({message: "Bad Request"});
   } else {
      var newId = movies[movies.length-1].id+1;
      movies.push({
         id: newId,
         name: req.body.name,
         year: req.body.year,
         rating: req.body.rating
      });
      res.json({message: "New movie created.", location: "/movies/" + newId});
   }
});

これにより、新しいムービーが作成され、movies変数に保存されます。このルートを確認するには、ターミナルに次のコードを入力します-

curl -X POST --data "name = Toy%20story&year = 1995&rating = 8.5" http://localhost:3000/movies

次の応答が表示されます-

{"message":"New movie created.","location":"/movies/105"}

これがmoviesオブジェクトに追加されたかどうかをテストするには、次のgetリクエストを実行します。 /movies/105再び。次の応答が表示されます-

{"id":105,"name":"Toy story","year":"1995","rating":"8.5"}

PUTルートとDELETEルートの作成に移りましょう。

PUTルート

PUTルートはPOSTルートとほぼ同じです。更新/作成されるオブジェクトのIDを指定します。次の方法でルートを作成します。

router.put('/:id', function(req, res){
   //Check if all fields are provided and are valid:
   if(!req.body.name ||
      !req.body.year.toString().match(/^[0-9]{4}$/g) || !req.body.rating.toString().match(/^[0-9]\.[0-9]$/g) ||
      !req.params.id.toString().match(/^[0-9]{3,}$/g)){
      
      res.status(400);
      res.json({message: "Bad Request"});
   } else {
      //Gets us the index of movie with given id.
      var updateIndex = movies.map(function(movie){
         return movie.id;
      }).indexOf(parseInt(req.params.id));
      
      if(updateIndex === -1){
         //Movie not found, create new
         movies.push({
            id: req.params.id,
            name: req.body.name,
            year: req.body.year,
            rating: req.body.rating
         });
         res.json({message: "New movie created.", location: "/movies/" + req.params.id});
      } else {
         //Update existing movie
         movies[updateIndex] = {
            id: req.params.id,
            name: req.body.name,
            year: req.body.year,
            rating: req.body.rating
         };
         res.json({message: "Movie id " + req.params.id + " updated.", 
            location: "/movies/" + req.params.id});
      }
   }
});

このルートは、上記の表で指定された機能を実行します。オブジェクトが存在する場合は、新しい詳細でオブジェクトを更新します。存在しない場合は、新しいオブジェクトが作成されます。ルートを確認するには、次のcurlコマンドを使用します。これにより、既存のムービーが更新されます。新しいムービーを作成するには、IDを存在しないIDに変更するだけです。

curl -X PUT --data "name = Toy%20story&year = 1995&rating = 8.5" 
http://localhost:3000/movies/101

Response

{"message":"Movie id 101 updated.","location":"/movies/101"}

ルートを削除

次のコードを使用して、削除ルートを作成します。−

router.delete('/:id', function(req, res){
   var removeIndex = movies.map(function(movie){
      return movie.id;
   }).indexOf(req.params.id); //Gets us the index of movie with given id.
   
   if(removeIndex === -1){
      res.json({message: "Not found"});
   } else {
      movies.splice(removeIndex, 1);
      res.send({message: "Movie id " + req.params.id + " removed."});
   }
});

他のルートと同じ方法でルートを確認してください。削除が成功すると(たとえばID 105)、次の出力が得られます-

{message: "Movie id 105 removed."}

最後に、 movies.js ファイルは次のようになります。

var express = require('express');
var router = express.Router();
var movies = [
   {id: 101, name: "Fight Club", year: 1999, rating: 8.1},
   {id: 102, name: "Inception", year: 2010, rating: 8.7},
   {id: 103, name: "The Dark Knight", year: 2008, rating: 9},
   {id: 104, name: "12 Angry Men", year: 1957, rating: 8.9}
];
router.get('/:id([0-9]{3,})', function(req, res){
   var currMovie = movies.filter(function(movie){
      if(movie.id == req.params.id){
         return true;
      }
   });
   
   if(currMovie.length == 1){
      res.json(currMovie[0])
   } else {
      res.status(404);  //Set status to 404 as movie was not found
      res.json({message: "Not Found"});
   }
});
router.post('/', function(req, res){
   //Check if all fields are provided and are valid:
   if(!req.body.name ||
      !req.body.year.toString().match(/^[0-9]{4}$/g) ||
      !req.body.rating.toString().match(/^[0-9]\.[0-9]$/g)){ res.status(400); res.json({message: "Bad Request"}); } else { var newId = movies[movies.length-1].id+1; movies.push({ id: newId, name: req.body.name, year: req.body.year, rating: req.body.rating }); res.json({message: "New movie created.", location: "/movies/" + newId}); } }); router.put('/:id', function(req, res) { //Check if all fields are provided and are valid: if(!req.body.name || !req.body.year.toString().match(/^[0-9]{4}$/g) ||
      !req.body.rating.toString().match(/^[0-9]\.[0-9]$/g) || !req.params.id.toString().match(/^[0-9]{3,}$/g)){
      res.status(400);
      res.json({message: "Bad Request"});
   } else {
      //Gets us the index of movie with given id.
      var updateIndex = movies.map(function(movie){
         return movie.id;
      }).indexOf(parseInt(req.params.id));
      
      if(updateIndex === -1){
         //Movie not found, create new
         movies.push({
            id: req.params.id,
            name: req.body.name,
            year: req.body.year,
            rating: req.body.rating
         });
         res.json({
            message: "New movie created.", location: "/movies/" + req.params.id});
      } else {
         //Update existing movie
         movies[updateIndex] = {
            id: req.params.id,
            name: req.body.name,
            year: req.body.year,
            rating: req.body.rating
         };
         res.json({message: "Movie id " + req.params.id + " updated.",
            location: "/movies/" + req.params.id});
      }
   }
});

router.delete('/:id', function(req, res){
   var removeIndex = movies.map(function(movie){
      return movie.id;
   }).indexOf(req.params.id); //Gets us the index of movie with given id.
   
   if(removeIndex === -1){
      res.json({message: "Not found"});
   } else {
      movies.splice(removeIndex, 1);
      res.send({message: "Movie id " + req.params.id + " removed."});
   }
});
module.exports = router;

これでRESTAPIが完成しました。これで、この単純なアーキテクチャスタイルとExpressを使用して、はるかに複雑なアプリケーションを作成できます。

足場を使用すると、簡単に作成できます。 skeleton for a web application。パブリックディレクトリの手動作成、ミドルウェアの追加、個別のルートファイルの作成などを行います。スキャフォールディングツールを使用すると、これらすべてがセットアップされ、アプリケーションの構築を直接開始できます。

使用する足場は Yeoman。それはのために作られた足場ツールですNode.jsただし、他のいくつかのフレームワーク(フラスコ、レール、ジャンゴなど)用のジェネレーターもあります。Yeomanをインストールするには、ターミナルで次のコマンドを入力します-

npm install -g yeoman

Yeomanは、ジェネレーターを使用してアプリケーションの足場を作ります。で利用可能なジェネレータをチェックするにはnpmヨーマンで使用するには、このリンクをクリックしてください。このチュートリアルでは、「generator-Express-simple」を使用します。このジェネレーターをインストールするには、ターミナルで次のコマンドを入力します-

npm install -g generator-express-simple

このジェネレーターを使用するには、次のコマンドを入力します-

yo express-simple test-app

アプリで何を使用したいかなど、いくつかの簡単な質問が表示されます。次の回答を選択するか、これらのテクノロジーについてすでに知っている場合は、どのようにしたいかを選択してください。

express-simple comes with bootstrap and jquery
[?] Select the express version you want: 4.x
[?] Do you want an mvc express app: Yes
[?] Select the css preprocessor you would like to use: sass
[?] Select view engine you would like to use: jade
[?] Select the build tool you want to use for this project: gulp
[?] Select the build tool you want to use for this project: gulp
[?] Select the language you want to use for the build tool: javascript
   create public/sass/styles.scss
   create public/js/main.js
   create views/layout.jade
   create views/index.jade
   create views/404.jade
   create app.js
   create config.js
   create routes/index.js
   create package.json
   create bower.json
identical .bowerrc
identical .editorconfig
identical .gitignore
identical .jshintrc
   create gulpfile.js

I'm all done. Running bower install & npm install for you to install the
required dependencies. If this fails, try running the command yourself.

次に、新しいアプリケーションを作成し、すべての依存関係をインストールし、アプリケーションにいくつかのページ(ホームページ、404 not foundページなど)を追加して、作業するディレクトリ構造を提供します。

このジェネレーターは、非常に単純な構造を作成します。Expressで利用できる多くのジェネレーターを調べて、自分に合ったものを選択してください。すべてのジェネレーターを操作する手順は同じです。ジェネレーターをインストールし、Yeomanを使用して実行する必要があります。いくつかの質問をしてから、回答に基づいてアプリケーションのスケルトンを作成します。

Expressでのエラー処理は、ミドルウェアを使用して行われます。しかし、このミドルウェアには特別な特性があります。エラー処理ミドルウェアは、エラー処理関数を除いて、他のミドルウェア関数と同じ方法で定義されます。MUST have four arguments 3つではなく– err, req, res, next。たとえば、エラーに対する応答を送信するには、-を使用できます。

app.use(function(err, req, res, next) {
   console.error(err.stack);
   res.status(500).send('Something broke!');
});

これまで、ルート自体のエラーを処理していました。エラー処理ミドルウェアを使用すると、エラーロジックを分離し、それに応じて応答を送信できます。ミドルウェアで説明したnext()メソッドは、次のステップに進みますmiddleware/route handler

エラー処理については、 next(err)関数。この関数を呼び出すと、すべてのミドルウェアがスキップされ、そのルートの次のエラーハンドラーと照合されます。例を通してこれを理解しましょう。

var express = require('express');
var app = express();

app.get('/', function(req, res){
   //Create an error and pass it to the next function
   var err = new Error("Something went wrong");
   next(err);
});

/*
 * other route handlers and middleware here
 * ....
 */

//An error handling middleware
app.use(function(err, req, res, next) {
   res.status(500);
   res.send("Oops, something went wrong.")
});

app.listen(3000);

このエラー処理ミドルウェアは、ルートの後に戦略的に配置したり、エラータイプを検出してそれに応じてクライアントに応答するための条件を含めることができます。上記のプログラムは、次の出力を表示します。

Expressは、デバッグモジュールを使用して、ルートマッチング、ミドルウェア機能、アプリケーションモードなどに関する情報を内部的にログに記録します。

Expressで使用されるすべての内部ログを表示するには、DEBUG環境変数を次のように設定します。 Express:* アプリ起動時−

DEBUG = express:* node index.js

以下の出力が表示されます。

これらのログは、アプリのコンポーネントが正しく機能していない場合に非常に役立ちます。この冗長な出力は少し圧倒されるかもしれません。DEBUG変数をログに記録する特定の領域に制限することもできます。たとえば、ロガーをアプリケーションとルーターに制限する場合は、次のコードを使用できます。

DEBUG = express:application,express:router node index.js

デバッグはデフォルトでオフになっており、実稼働環境では自動的にオンになります。デバッグは、ニーズに合わせて拡張することもできます。詳細については、npmページを参照してください。

物事の実行方法やファイル構造などが定義されているDjangoやRailsとは異なり、Expressは定義された方法に従いません。これは、アプリケーションを好きなように構成できることを意味します。ただし、アプリケーションのサイズが大きくなると、明確に定義された構造がないと、アプリケーションを維持することが非常に困難になります。この章では、アプリケーションを構築するために一般的に使用されるディレクトリ構造と関心の分離について説明します。

最初に、ノードおよびExpressアプリケーションを作成するためのベストプラクティスについて説明します。

  • 常にを使用してノードプロジェクトを開始します npm init

  • 常に依存関係をインストールします --save または --save-dev。これにより、別のプラットフォームに移動した場合でも、npminstallを実行してすべての依存関係をインストールできます。

  • 小文字のファイル名とキャメルケース変数を使用してください。npmモジュールを見ると、小文字で名前が付けられ、ダッシュで区切られています。これらのモジュールが必要な場合は常に、キャメルケースを使用してください。

  • node_modulesをリポジトリにプッシュしないでください。代わりに、npmはすべてを開発マシンにインストールします。

  • 使う config 変数を格納するファイル

  • ルートをグループ化して、独自のファイルに分離します。たとえば、RESTAPIページで見た映画の例のCRUD操作を考えてみましょう。

ディレクトリ構造

Expressのディレクトリ構造について説明しましょう。

ウェブサイト

Expressには、アプリケーションを作成するためのコミュニティ定義の構造がありません。以下は、ウェブサイトで主に使用されるプロジェクト構造です。

test-project/
   node_modules/
   config/
      db.js                //Database connection and configuration
      credentials.js       //Passwords/API keys for external services used by your app
      config.js            //Other environment variables
   models/                 //For mongoose schemas
      users.js
      things.js
   routes/                 //All routes for different entities in different files 
      users.js
      things.js
   views/
      index.pug
      404.pug
        ...
   public/                 //All static content being served
      images/
      css/
      javascript/
   app.js
   routes.js               //Require all routes in this and then require this file in 
   app.js 
   package.json

Expressを使用してWebサイトを構築する方法は他にもあります。MVCデザインパターンを使用してWebサイトを構築できます。詳細については、次のリンクにアクセスしてください。

https://code.tutsplus.com/tutorials/build-a-complete-mvc-website-with-expressjs--net-34168

そして、

https://www.terlici.com/2014/08/25/best-practices-express-structure.html。

RESTfulAPI

APIは設計が簡単です。パブリックディレクトリやビューディレクトリは必要ありません。次の構造を使用してAPIを構築します-

test-project/
   node_modules/
   config/
      db.js                //Database connection and configuration
      credentials.js       //Passwords/API keys for external services used by your app
   models/                 //For mongoose schemas
      users.js
      things.js
   routes/                 //All routes for different entities in different files 
      users.js
      things.js
   app.js
   routes.js               //Require all routes in this and then require this file in 
   app.js 
   package.json

ヨーマンジェネレーターを使用して、同様の構造を取得することもできます。

この章では、このチュートリアルで使用したさまざまなリソースを一覧表示します。

  • 最も重要なリンクはもちろんExpressAPIドキュメントです- https://expressjs.com/en/4x/api.html

  • ExpressのWebサイトで提供されているさまざまな側面のガイドも非常に役立ちます-

    • Routing

    • Middleware

    • エラー処理

    • Debugging

  • Expressで役立つ本やブログのリストは、次のURLで入手できます。 https://expressjs.com/en/resources/books-blogs.html

  • Expressで主に使用されるミドルウェアのリストは、次のURLで入手できます。 https://expressjs.com/en/resources/middleware.html

  • Expressのヒントとコツを紹介したこれらのブログが役立つかもしれません-

    • https://derickbailey.com/categories/tips-and-tricks/

    • https://scotch.io/tutorials/learn-to-use-the-new-router-in+-expressjs-4

  • アプリケーション構造- https://www.terlici.com/2014/08/25/best-practices-express-structure.html

  • RESTful API −

    • https://www.thepolyglotdeveloper.com/2015/10/create-a-simple-restful-api-with-node-js/

    • https://scotch.io/tutorials/build-a-restful-api-using-node-and-express-4

    • https://devcenter.heroku.com/articles/mean-apps-restful-api

    • https://pixelhandler.com/posts/develop-a-restful-api-using-nodejs-with-express-and-mongoose

    • http://cwbuecheler.com/web/tutorials/2014/restful-web-app-node-express-mongodb/

  • 高度な認証には、PassportJS-を使用します http://passportjs.org