ミドルウェアの使用
Express はルーティングおよびミドルウェアの Web フレームワークで、独自の最小限の機能を持っています。Express アプリケーションは、基本的にはミドルウェア関数の一連の呼び出しです。
Middleware 関数は、request object (req) にアクセスできる関数です。 response object (res) と、アプリケーションのリクエストレスポンスサイクルの次のミドルウェア関数。 次のミドルウェア関数は通常nextという名前の変数で表されます。 次のミドルウェア関数は通常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();});import express from 'express';
const app = express();
app.use((req, res, next) => { console.log('Time:', Date.now()); next();});import express, { type Express, type Request, type Response, type NextFunction } from 'express';
const app: Express = express();
app.use((req: Request, res: Response, next: NextFunction) => { console.log('Time:', Date.now()); next();});This example shows a middleware function mounted on the /user/:id path. この例では、/user/:id パスにマウントされたミドルウェア関数を示します。 関数は /user/:id パス上の任意のタイプの
HTTP リクエストに対して実行されます。
app.use('/user/:id', (req, res, next) => { console.log('Request Type:', req.method); next();});import { type Request, type Response, type NextFunction } from 'express';
app.use('/user/:id', (req: Request, res: Response, next: NextFunction) => { console.log('Request Type:', req.method); next();});This example shows a route and its handler function (middleware system). この例ではルートとハンドラ関数(ミドルウェアシステム)を示します。 関数は/user/:idパスへのGETリクエストを処理します。
app.get('/user/:id', (req, res, next) => { res.send('USER');});import { type Request, type Response, type NextFunction } from 'express';
app.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { res.send('USER');});Here is an example of loading a series of middleware functions at a mount point, with a mount path.
It illustrates a middleware sub-stack that prints request info for any type of HTTP request to the /user/:id path.
app.use( '/user/:id', (req, res, next) => { console.log('Request URL:', req.originalUrl); next(); }, (req, res, next) => { console.log('Request Type:', req.method); next(); });import { type Request, type Response, type NextFunction } from 'express';
app.use( '/user/:id', (req: Request, res: Response, next: NextFunction) => { console.log('Request URL:', req.originalUrl); next(); }, (req: Request, res: Response, next: NextFunction) => { console.log('Request Type:', req.method); next(); });Route handlers enable you to define multiple routes for a path. The example below defines two routes for GET requests to the /user/:id path. The second route will not cause any problems, but it will never get called because the first route ends the request-response cycle.
この例では、/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);});import { type Request, type Response, type NextFunction } from 'express';
app.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { console.log('ID:', req.params.id); next(); }, (req: Request, res: Response, next: NextFunction) => { res.send('User Info'); });
// handler for the /user/:id path, which prints the user IDapp.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { 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');});import { type Request, type Response, type NextFunction } from 'express';
app.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { // 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: Request, res: Response, next: NextFunction) => { // send a regular response res.send('regular'); });
// handler for the /user/:id path, which sends a special responseapp.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { 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');});import { type Request, type Response, type NextFunction } from 'express';
function logOriginalUrl(req: Request, res: Response, next: NextFunction) { console.log('Request URL:', req.originalUrl); next();}
function logMethod(req: Request, res: Response, next: NextFunction) { console.log('Request Type:', req.method); next();}
const logStuff = [logOriginalUrl, logMethod];app.get('/user/:id', logStuff, (req: Request, res: Response, next: NextFunction) => { res.send('User Info');});ルーターレベルのミドルウェア
ルータレベルのミドルウェアは、express.Router()のインスタンスにバインドされている場合を除き、アプリケーションレベルのミドルウェアと同じ方法で動作します。
const router = express.Router();import express from 'express';
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);import express from '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);import express, { type Express, type Request, type Response, type NextFunction } from 'express';
const app: Express = express();const router = express.Router();
// a middleware function with no mount path. This code is executed for every request to the routerrouter.use((req: Request, res: Response, next: NextFunction) => { 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: Request, res: Response, next: NextFunction) => { console.log('Request URL:', req.originalUrl); next(); }, (req: Request, res: Response, next: NextFunction) => { console.log('Request Type:', req.method); next(); });
// a middleware sub-stack that handles GET requests to the /user/:id pathrouter.get( '/user/:id', (req: Request, res: Response, next: NextFunction) => { // 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: Request, res: Response, next: NextFunction) => { // render a regular page res.render('regular'); });
// handler for the /user/:id path, which renders a special pagerouter.get('/user/:id', (req: Request, res: Response, next: NextFunction) => { 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);});import express from '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);});import express, { type Express, type Request, type Response, type NextFunction } from 'express';
const app: Express = express();const router = express.Router();
// predicate the router with a check and bail out when neededrouter.use((req: Request, res: Response, next: NextFunction) => { if (!req.headers['x-auth']) return next('router'); next();});
router.get('/user/:id', (req: Request, res: Response) => { res.send('hello, user!');});
// use the router and 401 anything falling throughapp.use('/admin', router, (req: Request, res: Response) => { res.sendStatus(401);});エラー処理のミドルウェア
Error-handling middleware always takes four arguments. You must provide four arguments to
identify it as an error-handling middleware function. Even if you don’t need to use the next
object, you must specify it to maintain the signature. 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!');});import { type Request, type Response, type NextFunction } from 'express';
app.use((err: Error, req: Request, res: Response, next: NextFunction) => { console.error(err.stack); res.status(500).send('Something broke!');});エラー処理ミドルウェアの詳細については、Error handlingを参照してください。
組み込みのミドルウェア
Starting with version 4.x, Express no longer depends on Connect. バージョン 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 serves static assets such as HTML files, images, and so on.
- express.json parses incoming requests with JSON payloads. NOTE: Available with Express 4.16.0+
- express.urlencoded parses incoming requests with URL-encoded payloads. NOTE: Available with Express 4.16.0+
Third-party middleware
サードパーティ製ミドルウェアを使用して、Express アプリに機能を追加します。
必要な機能のためにNode.jsモジュールをインストールし、アプリケーション・レベルまたはルータレベルでアプリケーションにロードします。
次の例は、cookie-parser関数cookie-parserのインストールとロードを示しています。
npm install cookie-parseryarn add cookie-parserpnpm add cookie-parserbun add cookie-parserconst express = require('express');const app = express();const cookieParser = require('cookie-parser');
// load the cookie-parsing middlewareapp.use(cookieParser());import express from 'express';import cookieParser from 'cookie-parser';
const app = express();
// load the cookie-parsing middlewareapp.use(cookieParser());import express, { type Express } from 'express';import cookieParser from 'cookie-parser';
const app: Express = express();
// load the cookie-parsing middlewareapp.use(cookieParser());Expressで一般的に使用されるサードパーティミドルウェア関数の部分的なリストについては、サードパーティミドルウェアを参照してください。