Articles

ミドルウェアを使用する

Posted on

ExpressはルーティングとミドルウェアのWebフレームワークで、それ自体は最小限の機能しか持っていません。

ミドルウェア関数とは、リクエストオブジェクト (req)、そしてアプリケーションのリクエスト-レスポンスサイクルにおける次のミドルウェア関数へのアクセスを持つ関数です。

ミドルウェア関数は次のようなタスクを実行できます。

  • 任意のコードを実行する
  • リクエストとレスポンスオブジェクトに変更を加える。
  • リクエスト-レスポンスのサイクルを終了する。
  • スタック内の次のミドルウェア関数を呼び出す。

現在のミドルウェア関数がリクエスト-レスポンスのサイクルを終了しない場合は、next()を呼び出して次のミドルウェア関数に制御を渡す必要があります。 そうしないと、リクエストが宙ぶらりんになってしまいます。

Expressアプリケーションでは、以下の種類のミドルウェアを使用することができます。

  • アプリケーションレベルのミドルウェア
  • ルーターレベルのミドルウェア
  • エラー処理用のミドルウェア
  • 組み込み型のミドルウェア
  • サードパーティ製のミドルウェア

アプリケーションレベルおよびルーターレベルのミドルウェアは、オプションのマウントパスでロードすることができます。また、一連のミドルウェア機能をまとめてロードすることもでき、マウントポイントにミドルウェアシステムのサブスタックを作成します。

アプリケーションレベルのミドルウェア

アプリケーションレベルのミドルウェアを、app.use()app.METHOD()の関数を使用して、appオブジェクトのインスタンスにバインドします。 ここで、METHODは、ミドルウェア機能が処理するリクエストのHTTPメソッド(GET、PUT、POSTなど)を小文字で表しています。

この例では、ミドルウェア関数にマウントパスを設定していません。

var express = require('express')var app = express()app.use(function (req, res, next) { console.log('Time:', Date.now()) next()})

この例では、ミドルウェア関数を/user/:idパスにマウントしています。

/user/:idパス上のあらゆるタイプのHTTPリクエストに対してこの関数が実行されます。

app.use('/user/:id', function (req, res, next) { console.log('Request Type:', req.method) next()})

この例では、ルートとそのハンドラ関数(ミドルウェアシステム)を示しています。 この関数は、/user/:idパスへのGETリクエストを処理します。

app.get('/user/:id', function (req, res, next) { res.send('USER')})

ここでは、一連のミドルウェア関数をマウントポイントにマウントパスでロードする例を示します。

app.use('/user/:id', function (req, res, next) { console.log('Request URL:', req.originalUrl) next()}, function (req, res, next) { console.log('Request Type:', req.method) next()})

ルートハンドラを使用すると、1つのパスに対して複数のルートを定義することができます。 以下の例では、/user/:id パスへの GET リクエストに対して 2 つのルートを定義しています。

この例では、/user/:idパスへのGETリクエストを処理するミドルウェアのサブスタックを示しています。

app.get('/user/:id', function (req, res, next) { console.log('ID:', req.params.id) next()}, function (req, res, next) { res.send('User Info')})// handler for the /user/:id path, which prints the user IDapp.get('/user/:id', function (req, res, next) { res.send(req.params.id)})

ルーターのミドルウェアスタックから残りのミドルウェア機能をスキップするには、next('route')next('route')app.METHOD()router.METHOD()を使用してロードされたミドルウェア関数でのみ動作します。

この例では、/user/:id パスへの GET リクエストを処理するミドルウェアのサブスタックを示しています。

app.get('/user/:id', function (req, res, next) { // if the user ID is 0, skip to the next route if (req.params.id === '0') next('route') // otherwise pass the control to the next middleware function in this stack else next()}, function (req, res, next) { // send a regular response res.send('regular')})// handler for the /user/:id path, which sends a special responseapp.get('/user/:id', function (req, res, next) { res.send('special')})

ミドルウェアは、再利用のために配列で宣言することもできます。

この例では、/user/:id パスへの GET リクエストを処理するミドルウェアのサブスタックを持つ配列を示しています

function logOriginalUrl (req, res, next) { console.log('Request URL:', req.originalUrl) next()}function logMethod (req, res, next) { console.log('Request Type:', req.method) next()}var logStuff = app.get('/user/:id', logStuff, function (req, res, next) { res.send('User Info')})

ルーターレベルのミドルウェア

ルーターレベルのミドルウェアは、アプリケーションレベルのミドルウェアと同じように動作します。 ただし、express.Router()のインスタンスにバインドされています。

var router = express.Router()

router.use()router.METHOD()の関数を使用して、ルーターレベルのミドルウェアをロードします。

次のコード例では、アプリケーションレベルのミドルウェアで示したミドルウェアシステムを、ルーターレベルのミドルウェアを使用して再現しています:

var express = require('express')var app = express()var router = express.Router()// a middleware function with no mount path. This code is executed for every request to the routerrouter.use(function (req, res, next) { console.log('Time:', Date.now()) next()})// a middleware sub-stack shows request info for any type of HTTP request to the /user/:id pathrouter.use('/user/:id', function (req, res, next) { console.log('Request URL:', req.originalUrl) next()}, function (req, res, next) { console.log('Request Type:', req.method) next()})// a middleware sub-stack that handles GET requests to the /user/:id pathrouter.get('/user/:id', function (req, res, next) { // if the user ID is 0, skip to the next router if (req.params.id === '0') next('route') // otherwise pass control to the next middleware function in this stack else next()}, function (req, res, next) { // render a regular page res.render('regular')})// handler for the /user/:id path, which renders a special pagerouter.get('/user/:id', function (req, res, next) { console.log(req.params.id) res.render('special')})// mount the router on the appapp.use('/', router)

ルーターのミドルウェア関数の残りをスキップするには、next('router')を呼び出して、ルーターインスタンスから制御を戻します。

この例では、/user/:id パスへの GET リクエストを処理するミドルウェアのサブスタックを示しています。

var express = require('express')var app = express()var router = express.Router()// predicate the router with a check and bail out when neededrouter.use(function (req, res, next) { if (!req.headers) return next('router') next()})router.get('/user/:id', function (req, res) { res.send('hello, user!')})// use the router and 401 anything falling throughapp.use('/admin', router, function (req, res) { res.sendStatus(401)})

エラー処理用ミドルウェア

エラー処理用ミドルウェアは常に 4 つの引数を取ります。 エラー処理ミドルウェアの関数であることを識別するために、4つの引数を提供する必要があります。 また、nextnextオブジェクトが通常のミドルウェアとして解釈され、エラー処理に失敗してしまいます。

エラー処理を行うミドルウェアの関数は、他のミドルウェアの関数と同じように定義します。ただし、引数は3つではなく4つとし、具体的には(err, req, res, next)というシグネチャーを付けます。

内蔵ミドルウェア

バージョン 4.x 以降、Express は Connect に依存しなくなりました。

Expressには以下のミドルウェアが組み込まれています。

  • express.staticは、HTMLファイルや画像などの静的資産を提供します。
  • express.jsonは、JSONペイロードを持つ受信リクエストを解析します。 注: Express 4.16.0+ で利用可能です。
  • express.urlencoded は、URL エンコードされたペイロードで受信したリクエストを解析します。

    必要な機能のNode.jsモジュールをインストールし、アプリケーションレベルまたはルーターレベルでアプリにロードします。

    以下の例では、クッキーを解析するミドルウェア関数 cookie-parser をインストールしてロードする例を示しています。

    $ npm install cookie-parser
    var express = require('express')var app = express()var cookieParser = require('cookie-parser')// load the cookie-parsing middlewareapp.use(cookieParser())

    Expressでよく使われるサードパーティ製ミドルウェア関数の一部については、「サードパーティ製ミドルウェア」を参照してください。 サードパーティ製ミドルウェア

    Expressでよく使われるサードパーティ製ミドルウェアの機能の一部をご紹介します。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です