ミドルウェアの使用
Express はルーティングおよびミドルウェアの Web フレームワークで、独自の最小限の機能を持っています。Express アプリケーションは、基本的にはミドルウェア関数の一連の呼び出しです。
Middleware 関数は、request object (req) にアクセスできる関数です。 response object (res) と、アプリケーションのリクエストレスポンスサイクルの次のミドルウェア関数。 次のミドルウェア関数は通常nextという名前の変数で表されます。
ミドルウェア機能は以下のタスクを実行できます。
- 任意のコードを実行します。
- リクエストとレスポンスオブジェクトに変更を加えます。
- リクエストレスポンスサイクルを終了します。
- スタック内の次のミドルウェア関数を呼び出します。
現在のミドルウェア関数がリクエスト応答サイクルを終了しない場合は、次のミドルウェア関数に制御を渡すために next() を呼び出す必要があります。 そうでなければ、リクエストはハングアップのままになります。
Express アプリケーションでは、次のタイプのミドルウェアを使用できます。
- Application-level middleware
- Router-level middleware
- Error-handling middleware
- Built-in middleware
- Third-party middleware
アプリケーションレベルおよびルーターレベルのミドルウェアは、任意のマウントパスでロードできます。 また、一連のミドルウェア関数を一緒にロードして、マウントポイントでミドルウェアシステムのサブスタックを作成することもできます。
アプリケーションレベルのミドルウェア
app.use() と app() を使用して、アプリケーションレベルのミドルウェアを app object のインスタンスにバインドします。 ETHOD()関数。METHODはミドルウェア関数が小文字で処理するHTTPメソッドです(GET、PUT、POSTなど)。
この例では、マウントパスのないミドルウェア関数を示します。 この関数はアプリがリクエストを受け取るたびに実行されます。
const express = require('express');const app = express();
app.use((req, res, next) => { console.log('Time:', Date.now()); next();});この例では、/user/:id パスにマウントされたミドルウェア関数を示します。 関数は /user/:id パス上の任意のタイプの
HTTP リクエストに対して実行されます。
app.use('/user/:id', (req, res, next) => { console.log('Request Type:', req.method); next();});この例ではルートとハンドラ関数(ミドルウェアシステム)を示します。 関数は/user/:idパスへのGETリクエストを処理します。
app.get('/user/:id', (req, res, next) => { res.send('USER');});次に、マウントパスを持つ一連のミドルウェア関数をマウントポイントにロードする例を示します。
これは /user/:id パスにHTTPリクエスト情報を出力するミドルウェアのサブスタックを示しています。
app.use( '/user/:id', (req, res, next) => { console.log('Request URL:', req.originalUrl); next(); }, (req, res, next) => { console.log('Request Type:', req.method); next(); });ルートハンドラを使用すると、パスに複数のルートを定義できます。 下の例では、/user/:idパスへのGETリクエストに対する2つのルートを定義しています。 2番目のルートは問題を引き起こすことはありませんが、最初のルートはリクエスト応答サイクルを終了するため、呼び出されることはありません。
この例では、/user/:idパスへのGETリクエストを処理するミドルウェアサブスタックを示します。
app.get( '/user/:id', (req, res, next) => { console.log('ID:', req.params.id); next(); }, (req, res, next) => { res.send('User Info'); });
// handler for the /user/:id path, which prints the user IDapp.get('/user/:id', (req, res, next) => { res.send(req.params.id);});他のミドルウェア関数をルータのミドルウェアスタックからスキップするには、次のルートに制御を渡すために next('route') を呼び出します。
next('route') は、
app.METHOD() または router.METHOD() 関数を使用してロードされたミドルウェア関数でのみ動作します。
この例では、/user/:idパスへのGETリクエストを処理するミドルウェアサブスタックを示します。
app.get( '/user/:id', (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(); }, (req, res, next) => { // send a regular response res.send('regular'); });
// handler for the /user/:id path, which sends a special responseapp.get('/user/:id', (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();}
const logStuff = [logOriginalUrl, logMethod];app.get('/user/:id', logStuff, (req, res, next) => { res.send('User Info');});ルーターレベルのミドルウェア
ルータレベルのミドルウェアは、express.Router()のインスタンスにバインドされている場合を除き、アプリケーションレベルのミドルウェアと同じ方法で動作します。
const router = express.Router();router.use()とrouter.METHOD()関数を使ってルーターレベルのミドルウェアをロードします。
次のコード例は、ルーターレベルのミドルウェアを使用して、アプリケーションレベルのミドルウェアに対して上記のミドルウェアシステムを複製します。
const express = require('express');const app = express();const router = express.Router();
// a middleware function with no mount path. This code is executed for every request to the routerrouter.use((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', (req, res, next) => { console.log('Request URL:', req.originalUrl); next(); }, (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', (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(); }, (req, res, next) => { // render a regular page res.render('regular'); });
// handler for the /user/:id path, which renders a special pagerouter.get('/user/:id', (req, res, next) => { console.log(req.params.id); res.render('special');});
// mount the router on the appapp.use('/', router);ルーターのミドルウェア関数の残りをスキップするには、next('router')
を呼び出してルーターインスタンスからコントロールを渡します。
この例では、/user/:idパスへのGETリクエストを処理するミドルウェアサブスタックを示します。
const express = require('express');const app = express();const router = express.Router();
// predicate the router with a check and bail out when neededrouter.use((req, res, next) => { if (!req.headers['x-auth']) return next('router'); next();});
router.get('/user/:id', (req, res) => { res.send('hello, user!');});
// use the router and 401 anything falling throughapp.use('/admin', router, (req, res) => { res.sendStatus(401);});エラー処理のミドルウェア
エラー処理ミドルウェアは常に_4つの引数を取ります。 エラー処理ミドルウェア関数として
識別するには、4つの引数を指定する必要があります。 next
オブジェクトを使用しなくても、署名を維持するために指定する必要があります。 Otherwise, the next object will be
interpreted as regular middleware and will fail to handle errors.
他のミドルウェア関数と同じ方法でエラー処理ミドルウェア関数を定義します 3 つの代わりに 4 つの引数を指定する場合を除き、特に `(err, req, res, next) というシグネチャを使用します。
app.use((err, req, res, next) => { console.error(err.stack); res.status(500).send('Something broke!');});エラー処理ミドルウェアの詳細については、Error handlingを参照してください。
組み込みのミドルウェア
バージョン 4.x 以降、Express は Connect に依存しなくなりました。 The middleware functions that were previously included with Express are now in separate modules; see the list of middleware functions.
Express には次のミドルウェア関数が組み込まれています。
- express.static は、HTML ファイル、画像などの静的なアセットを提供します。
- express.json は、JSON ペイロードで受信したリクエストを解析します。 **注意: Express 4.16.0+で利用可能
- express.urlencoded は、URLエンコードされたペイロードで受信するリクエストを解析します。 **注意: Express 4.16.0+で利用可能
サードパーティのミドルウェア
サードパーティ製ミドルウェアを使用して、Express アプリに機能を追加します。
必要な機能のためにNode.jsモジュールをインストールし、アプリケーション・レベルまたはルータレベルでアプリケーションにロードします。
次の例は、cookie-parser関数cookie-parserのインストールとロードを示しています。
$ npm install cookie-parserconst express = require('express');const app = express();const cookieParser = require('cookie-parser');
// load the cookie-parsing middlewareapp.use(cookieParser());Expressで一般的に使用されるサードパーティミドルウェア関数の部分的なリストについては、サードパーティミドルウェアを参照してください。