Express.jsにおけるミドルウェアとapp.useの詳細解説
Express.jsは、Node.js用の軽量で柔軟なWebフレームワークです。その中核となるのがミドルウェアと呼ばれる機能です。ミドルウェアは、リクエストとレスポンスの処理フローに介入し、様々な処理を挿入できる仕組みです。
本記事では、ミドルウェアとapp.use
関数の詳細について、分かりやすく解説します。
ミドルウェアとは
ミドルウェアは、リクエストとレスポンスの処理フローに介入し、様々な処理を挿入できる関数です。具体的には、以下のようなことができます。
- 認証・認可: ユーザーの認証や認可を行い、アクセス権限を制御する
- ロギング: リクエストとレスポンスに関する情報を記録する
- データの変換: リクエストやレスポンスのデータ形式を変換する
- キャッシュ: 静的コンテンツをキャッシュしてパフォーマンスを向上させる
- エラー処理: エラーが発生した際の処理をハンドリングする
ミドルウェアは、単独で動作することも、複数を組み合わせることもできます。また、組み込みのミドルウェアに加え、サードパーティ製のミドルウェアも豊富に用意されています。
app.use関数
app.use
関数は、ミドルウェアをExpressアプリケーションに登録するために使用されます。引数として、ミドルウェア関数とオプションのパスを渡します。パスを指定した場合、そのパスに一致するリクエストのみでミドルウェアが実行されます。
app.use(middlewareFunction); // すべてのパスでミドルウェアを実行
app.use('/users', middlewareFunction); // '/users' パスに一致するリクエストのみでミドルウェアを実行
ミドルウェアの処理フロー
ミドルウェアは、リクエストとレスポンスオブジェクトを引数として受け取り、処理を行います。処理が完了したら、next
関数を呼び出す必要があります。next
関数を呼び出すことで、次のミドルウェアまたはルーティングハンドラに処理を移行します。
app.use((req, res, next) => {
// 処理
next();
});
ミドルウェアの種類
ミドルウェアは、様々な種類に分類できます。代表的な種類は以下の通りです。
- アプリケーションレベルミドルウェア: アプリケーション全体に適用されるミドルウェア
- ルーターレベルミドルウェア: 特定のパスにのみ適用されるミドルウェア
- 組み込みミドルウェア: Expressに標準で用意されているミドルウェア
- サードパーティ製ミドルウェア: 開発者が作成したミドルウェア
ミドルウェアは、Express.jsにおける重要な機能であり、様々な処理を柔軟に挿入することができます。app.use
関数を使用してミドルウェアを登録し、アプリケーションの機能を拡張することができます。
app.use((req, res, next) => {
const authToken = req.headers['Authorization'];
if (!authToken) {
return res.status(401).send('Unauthorized');
}
// トークンを検証する処理
next();
});
ロギングミドルウェア
以下のコードは、ロギングミドルウェアの例です。このミドルウェアは、リクエストとレスポンスに関する情報をコンソールに出力します。
app.use((req, res, next) => {
const method = req.method;
const url = req.url;
const startTime = Date.now();
console.log(`${method} ${url} started`);
res.on('finish', () => {
const endTime = Date.now();
const duration = endTime - startTime;
console.log(`${method} ${url} finished in ${duration}ms`);
});
next();
});
データ変換ミドルウェア
以下のコードは、データ変換ミドルウェアの例です。このミドルウェアは、リクエストボディをJSON形式からオブジェクト形式に変換します。
app.use(express.json()); // JSONボディを自動的に解析するミドルウェアを登録
app.use((req, res, next) => {
req.body = JSON.parse(req.body);
next();
});
キャッシュミドルウェア
以下のコードは、キャッシュミドルウェアの例です。このミドルウェアは、静的コンテンツをキャッシュしてパフォーマンスを向上させます。
app.use(express.static('public', {
maxAge: 600000 // キャッシュ期間を10分 (600000ミリ秒) に設定
}));
エラー処理ミドルウェア
以下のコードは、エラー処理ミドルウェアの例です。このミドルウェアは、エラーが発生した際に適切なエラーメッセージを返します。
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Internal Server Error');
});
Express.jsにおけるミドルウェアの活用方法
カスタムミドルウェアの作成
組み込みのミドルウェアに加え、独自のミドルウェアを作成することもできます。これは、特定のニーズに合わせた処理を実行したい場合に役立ちます。
カスタムミドルウェアを作成するには、以下の手順に従います。
- ミドルウェア関数を定義します。この関数は、
req
、res
、next
の3つの引数を受け取ります。 req
とres
オブジェクトを使用して、リクエストとレスポンスに関する処理を行います。- 処理が完了したら、
next
関数を呼び出して、次のミドルウェアまたはルーティングハンドラに処理を移行します。
app.use((req, res, next) => {
// 処理
next();
});
エラーハンドリング
エラーハンドリングは、ミドルウェアで重要な役割を果たします。エラーが発生した場合は、適切なエラーメッセージをユーザーに返さなければなりません。
Express.jsは、エラーハンドリング用の組み込みミドルウェアを提供しています。このミドルウェアは、エラーが発生したときに自動的に呼び出され、デフォルトのエラーメッセージを返します。
独自のエラーハンドリングロジックを実装したい場合は、カスタムミドルウェアを作成する必要があります。このミドルウェアは、エラーオブジェクトを引数として受け取り、エラーメッセージの生成、ログ記録、適切なステータスコードの返などを処理することができます。
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Internal Server Error');
});
ルーティング
ミドルウェアを使用して、ルーティングロジックをカスタマイズすることもできます。Express.jsは、デフォルトのルーティングシステムを提供していますが、より柔軟なルーティングが必要な場合は、カスタムミドルウェアを作成することができます。
カスタムルーティングミドルウェアは、req.url
プロパティを使用してリクエストパスを検査し、それに応じて処理を実行することができます。
app.use('/users', (req, res, next) => {
// /users パスに一致するリクエストのみで処理を実行
next();
});
app.get('/users/:id', (req, res) => {
const userId = req.params.id;
// 特定のユーザーに関する処理
});
サブアプリケーション
サブアプリケーションは、特定の機能をグループ化するために使用できる強力なツールです。サブアプリケーションは、独自のミドルウェア、ルーティング、コントローラーを持つ独立したアプリケーションとして機能します。
サブアプリケーションを作成するには、express()
関数を呼び出して新しい Express インスタンスを作成し、それをメインアプリケーションにマウントします。
const userApp = express();
userApp.use((req, res, next) => {
// ユーザーサブアプリケーション用のミドルウェア
next();
});
userApp.get('/profile', (req, res) => {
// ユーザーのプロフィールに関する処理
});
app.use('/users', userApp);
サードパーティ製ミドルウェア
Express.js には、様々なサードパーティ製ミドルウェアが用意されています。これらのミドルウェアは、認証、セッション管理、ファイルアップロードなどの一般的なタスクを処理するために使用できます。
サードパーティ製ミドルウェアを使用するには、通常、npm
または yarn
を使用してインストールする必要があります。インストール後、ミドルウェアをアプリケーションに登録して使用することができます。
const expressSession = require('express-session');
app.use(expressSession({
secret: 'my secret key',
resave: false,
saveUninitialized: true
}));
node.js express