このページを翻訳

ミドルウェアの使用

Express is a routing and middleware web framework with minimal functionality of its own: an Express application is essentially a series of middleware function calls executed during the request-response cycle.

Middleware functions are functions that have access to:

  • The request object (req)
  • The response object (res)
  • The next middleware function in the application’s request-response cycle, commonly named next

ミドルウェア機能は以下のタスクを実行できます。

  • 任意のコードを実行します。
  • Modify the request and response objects.
  • リクエストレスポンスサイクルを終了します。
  • Pass control to the next middleware function.

If a middleware function does not end the request-response cycle, it must call next() to pass control to the next middleware function. そうでなければ、リクエストはハングアップのままになります。

Express アプリケーションでは、次のタイプのミドルウェアを使用できます。

アプリケーションレベルおよびルーターレベルのミドルウェアは、任意のマウントパスでロードできます。 また、一連のミドルウェア関数を一緒にロードして、マウントポイントでミドルウェアシステムのサブスタックを作成することもできます。 Multiple middleware functions can also be loaded together, which creates a middleware sub-stack at a mount point.

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

Bind application-level middleware to an instance of the app object by using the app.use() and app.METHOD() functions, where METHOD is the lowercase HTTP method of the request that the middleware function handles, such as get, post, put, or delete.

Middleware without a mount path

The following middleware function runs every time the app receives a request:

index.cjs
const express = require('express');
const app = express();
app.use((req, res, next) => {
console.log('Time:', Date.now());
next();
});

Middleware mounted on a path

The following middleware function runs for any type of HTTP request on the /user/:id path:

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

Route handlers

This example shows a route and its handler function (middleware system). この例ではルートとハンドラ関数(ミドルウェアシステム)を示します。 関数は/user/:idパスへのGETリクエストを処理します。

app.get('/user/:id', (req, res) => {
res.send('USER');
});

Middleware sub-stacks

Multiple middleware functions can be loaded together at a mount point to form a middleware sub-stack. This example 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();
}
);

Multiple route handlers

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.

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

Skipping to the next route

Call next('route') to skip the remaining middleware functions in a router middleware stack and pass control to the next route.

next('route') は、 app.METHOD() または router.METHOD() 関数を使用してロードされたミドルウェア関数でのみ動作します。

In the following example, if the user ID is 0, the first handler skips to the next route, which sends a special response:

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) => {
// send a regular response
res.send('regular');
}
);
// handler for the /user/:id path, which sends a special response
app.get('/user/:id', (req, res) => {
res.send('special');
});

Reusable middleware arrays

Middleware functions can also be grouped into arrays for better reusability. この例では、/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) => {
res.send('User Info');
});

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

Router-level middleware works the same way as application-level middleware, except it is bound to an instance of express.Router().

const router = express.Router();

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

次のコード例は、ルーターレベルのミドルウェアを使用して、アプリケーションレベルのミドルウェアに対して上記のミドルウェアシステムを複製します。

index.cjs
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 router
router.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 path
router.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 path
router.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 control to the next middleware function in this stack
else next();
},
(req, res) => {
// render a regular page
res.render('regular');
}
);
// handler for the /user/:id path, which renders a special page
router.get('/user/:id', (req, res) => {
console.log(req.params.id);
res.render('special');
});
// mount the router on the app
app.use('/', router);

Skipping out of a router

Use next('router') to skip the rest of the router’s middleware functions and pass control back out of the router instance.

In the following example, the router only responds when the request includes an x-auth header. Otherwise, next('router') exits the router and the app responds with a 401 status:

index.cjs
const express = require('express');
const app = express();
const router = express.Router();
// predicate the router with a check and bail out when needed
router.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 through
app.use('/admin', router, (req, res) => {
res.sendStatus(401);
});

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

他のミドルウェア関数と同じ方法でエラー処理ミドルウェア関数を定義します 3 つの代わりに 4 つの引数を指定する場合を除き、特に `(err, req, res, next) というシグネチャを使用します。

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

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.

組み込みのミドルウェア

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

Third-party middleware

サードパーティ製ミドルウェアを使用して、Express アプリに機能を追加します。

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

次の例は、cookie-parser関数cookie-parserのインストールとロードを示しています。

Terminal window
npm install cookie-parser
index.cjs
const express = require('express');
const app = express();
const cookieParser = require('cookie-parser');
// load the cookie-parsing middleware
app.use(cookieParser());