app.param()
| 対応: | Express 4(2014) |
|---|
『Express』の『app.param()』は、ルートパラメータに対するコールバックを登録するメソッドです。URLパラメータが一致したリクエストに対して、ルートハンドラーより先にコールバックが実行されます。パラメータの値の検証・変換・データ取得といった前処理を一箇所にまとめられるため、複数のルートで同じパラメータを扱う場合にコードの重複を避けられます。
構文
// 単一のパラメータ名に対してコールバックを登録します app.param(name, callback); // 複数のパラメータ名をまとめて登録します app.param([name1, name2], callback);
引数一覧
| 引数 | 型 | 必須 | 概要 |
|---|---|---|---|
| name | 文字列 / 配列 | 必須 | コールバックを登録するルートパラメータ名を指定します。配列で複数まとめて指定することもできます。 |
| callback | 関数 | 必須 | パラメータが一致したときに呼び出されるコールバック関数を指定します。 |
コールバック関数の引数
| 引数 | 概要 |
|---|---|
| req | リクエストオブジェクトです。 |
| res | レスポンスオブジェクトです。 |
| next | 次のミドルウェアまたはルートハンドラーへ処理を渡す関数です。 |
| value | URLパラメータの実際の値です(文字列)。 |
| name | パラメータ名(文字列)です。複数パラメータをまとめて登録した場合に便利です。 |
サンプルコード
パラメータの値の検証・データ取得・複数パラメータへの一括登録といった代表的な使い方を紹介します。
var express = require('express');
var app = express();
// --- サンプル用のデータ ---
var users = [
{ id: 1, name: '山田太郎', role: 'admin' },
{ id: 2, name: '鈴木花子', role: 'user' },
{ id: 3, name: '田中次郎', role: 'user' }
];
// --- app.param() によるパラメータコールバックの登録 ---
// :userId パラメータが含まれるルートへのリクエストで事前に呼び出されます
app.param('userId', function(req, res, next, value) {
// value にはURLパラメータの文字列値が渡されます(例: '2')
var id = parseInt(value, 10);
// IDが数値でない場合は400エラーを返して処理を止めます
if (isNaN(id)) {
return res.status(400).json({ error: 'userIdは数値で指定してください' });
}
// ユーザー一覧からIDが一致するユーザーを検索します
var user = null;
for (var i = 0; i < users.length; i++) {
if (users[i].id === id) {
user = users[i];
break;
}
}
// ユーザーが見つからない場合は404エラーを返します
if (!user) {
return res.status(404).json({ error: 'ユーザーが見つかりません' });
}
// 取得したユーザーをreqオブジェクトに格納し、後続のハンドラーで使えるようにします
req.user = user;
// next() を呼び出して次のミドルウェアまたはルートハンドラーへ進みます
next();
});
// --- :userId を含むルート ---
// GETリクエスト: 指定したユーザーの情報を返します
// app.param() で検証・取得済みの req.user をそのまま利用できます
app.get('/users/:userId', function(req, res) {
res.json(req.user);
});
// GETリクエスト: 指定したユーザーのロール情報を返します
// こちらのルートでも同じ app.param() コールバックが自動的に実行されます
app.get('/users/:userId/role', function(req, res) {
res.json({ userId: req.user.id, role: req.user.role });
});
// DELETEリクエスト: 指定したユーザーを削除します
app.delete('/users/:userId', function(req, res) {
// app.param() によってすでに存在確認が済んでいるので、ここで再チェック不要です
console.log('削除対象ユーザー:', req.user.name);
res.json({ message: req.user.name + ' を削除しました' });
});
// --- 複数パラメータをまとめて登録する例 ---
// :year と :month の両方に同じバリデーションコールバックを登録します
app.param(['year', 'month'], function(req, res, next, value, name) {
var num = parseInt(value, 10);
// 数値でない場合は400エラーを返します(name には 'year' または 'month' が入ります)
if (isNaN(num) || num <= 0) {
return res.status(400).json({ error: name + ' は正の整数で指定してください' });
}
// 検証済みの数値をreqに格納します(例: req.year、req.month)
req[name] = num;
next();
});
// GETリクエスト: /archive/:year/:month の形式でアーカイブを取得します
app.get('/archive/:year/:month', function(req, res) {
// app.param() でバリデーション済みの req.year・req.month を使います
res.json({
year: req.year,
month: req.month,
label: req.year + '年' + req.month + '月のアーカイブ'
});
});
// --- サーバーの起動 ---
app.listen(3000, function() {
console.log('サーバーを起動しました: http://localhost:3000');
});
概要
『app.param()』を使うと、URLパラメータに対する検証・変換・データ取得といった前処理を1箇所にまとめられます。同じパラメータを使うルートが複数あっても、各ルートハンドラーに前処理コードを繰り返し書く必要がなくなります。
コールバックはパラメータが一致するルートへのリクエストごとに1度だけ実行されます。next() を呼び出すことで後続のルートハンドラーへ処理が渡されます。エラーが発生した場合は next() を呼ばずにレスポンスを返すことで、ルートハンドラーへの処理進行を止められます。
ルーティングをモジュールに分割している場合は、express.Router() にも同様の router.param() メソッドがあります。アプリケーション全体ではなく特定のルーターグループだけにパラメータコールバックを適用したいときは router.param() を使うと整理しやすくなります。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。