Express.jsのミドルウェアを作成し使用する方法
Express.jsのミドルウェアの作成と使用方法を紹介します。コードもGit Hubに掲載するので参考にしてください。
概要
Expressは、ミドルウェア(middleware)を使用して、リクエストとレスポンスの間で処理を実行する能力を持つフレームワークです。ミドルウェアは、リクエストオブジェクト、レスポンスオブジェクト、および次のミドルウェア関数へのアクセスを提供します。ミドルウェアは、Expressのルートハンドラ内で使用されます。
ここでは、以下のバージョンを使用して、Expressでミドルウェアを作成する方法を紹介します。
- Express v4.17.1
- nodejs v19.7.0
また、今回作成するコードは全て、GitHubに掲載しています。
ミドルウェアの定義方法
Express.jsでは、ミドルウェアを使用するための主な5つの方法があります。
- アプリケーションレベルミドルウェア
全体のアプリケーションに適用されるミドルウェアです。app.use()
またはapp.METHOD()
を用いて定義します。
const express = require('express');
const app = express();
app.use((req, res, next) => {
console.log('This is an application-level middleware');
next();
});
- ルーターレベルミドルウェア
特定のルート、もしくはルートグループに対して適用されるミドルウェアです。router.use()
またはrouter.METHOD()
を用いて定義します。
const express = require('express');
const router = express.Router();
router.use((req, res, next) => {
console.log('This is a router-level middleware');
next();
});
app.use('/api', router);
- 組み込みミドルウェア
Expressに組み込まれているミドルウェア関数です。例えばexpress.static
、express.json
、express.urlencoded
などがあります。
app.use(express.json()); // for parsing application/json
app.use(express.static('public')); // to serve static files
- サードパーティミドルウェア
サードパーティによって提供されるミドルウェアです。app.use()
またはrouter.use()
で適用します。例えば、Cookieをパースするためのcookie-parser
やHTTPリクエストログを作成するためのmorgan
などがあります。
const cookieParser = require('cookie-parser');
app.use(cookieParser());
- エラーハンドリングミドルウェア
他のミドルウェア関数
で発生したエラーを処理するためのミドルウェアです。通常は4つの引数(err
, req
, res
, next
)を持ちます。
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});
これらのミドルウェアは、個々の要求がアプリケーションを通過する際に特定のポイントで機能を実行するのに役立ちます。それぞれのミドルウェア関数は、要求-応答サイクルを終了させるか、スタック内の次のミドルウェア関数に要求と応答オブジェクトを渡すかします。
アプリケーションレベルミドルウェアを作成する方法
以下の例では、myMiddleware
という名前のアプリケーションレベルのミドルウェアを作成します。
application.js
const express = require('express');
const app = express();
function myMiddleware(req, res, next) {
// ミドルウェアの処理
console.log('ミドルウェアの実行');
next();
}
app.use(myMiddleware);
app.get('/', (req, res) => {
res.send({ message: 'Hello, World!' });
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
解説
- Expressのインスタンスを作成
const express = require('express');
const app = express();
Expressモジュールをインポートし、そのインスタンスを作成します。
- ミドルウェア関数の定義
function myMiddleware(req, res, next) {
// ミドルウェアの処理
console.log('ミドルウェアの実行');
next();
}
myMiddleware
という名前のミドルウェア関数を定義します。この関数は、リクエストとレスポンスオブジェクトを引数に取り、次のミドルウェアまたはルートハンドラーに処理を渡すためのnext
関数を呼び出します。
- ミドルウェアの追加
app.use(myMiddleware);
Expressアプリケーションにミドルウェアを追加します。app.use
メソッドを使用して、myMiddleware
関数をミドルウェアとして登録します。このミドルウェアは、全てのルートハンドラーが実行される前に呼び出されます。
- ルートハンドラの定義
app.get('/', (req, res) => {
res.send({ message: 'Hello, World!' });
});
/
というパスへのGETリクエストをハンドリングするルートハンドラーを定義します。リクエストが来ると、{ message: 'Hello, World!' }
というオブジェクトをレスポンスとして返します。
- サーバーの起動
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
Expressのインスタンスをポート3000でリッスンさせ、サーバーを起動します。サーバーが起動したら、“Server is running on port 3000"というメッセージをコンソールに出力します。
テスト
curl -X GET http://localhost:3000
ルーターレベルミドルウェアを作成する方法
以下の例では、myMiddleware
という名前のルーターレベルのミドルウェアを作成します。
routeMiddleware.js
function myMiddleware(req, res, next) {
// ミドルウェアの処理
console.log('ミドルウェアの実行');
next();
}
module.exports = myMiddleware;
解説
- ミドルウェア関数の定義
function myMiddleware(req, res, next) {
// ミドルウェアの処理
console.log('ミドルウェアの実行');
next();
}
myMiddleware
という名前のミドルウェア関数を定義します。この関数は、リクエストとレスポンスオブジェクトを引数に取り、次のミドルウェアまたはルートハンドラーに処理を渡すためのnext
関数を呼び出します。
- ミドルウェア関数のエクスポート
module.exports = myMiddleware;
myMiddleware
関数をエクスポートします。これにより、他のファイルからこのミドルウェア関数をインポートして使用することができます。
routeMain.js
const express = require('express');
const app = express();
const myMiddleware = require('./myMiddleware');
app.use(myMiddleware);
app.get('/', (req, res) => {
res.send({ message: 'Hello, World!' });
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
解説
- Expressのインスタンスの作成
const express = require('express');
const app = express();
Expressモジュールをインポートし、そのインスタンスを作成します。
- ミドルウェアのインポート
const myMiddleware = require('./myMiddleware');
myMiddleware
という名前のミドルウェア関数を別のファイルからインポートします。
- ミドルウェアの登録
app.use(myMiddleware);
app.use()
メソッドを使用して、インポートしたミドルウェア関数をExpressアプリケーションに登録します。これにより、このミドルウェア関数はアプリケーションの全てのルートに対して実行されます。
- ルートハンドラの定義
app.get('/', (req, res) => {
res.send({ message: 'Hello, World!' });
});
/
というパスへのGETリクエストをハンドリングするルートハンドラーを定義します。リクエストが来ると、{ message: 'Hello, World!' }
というJSONレスポンスを返します。
- サーバーの起動
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
Expressのインスタンスをポート3000でリッスンさせ、サーバーを起動します。サーバーが起動したら、“Server is running on port 3000"というメッセージをコンソールに出力します。
テスト
curl -X GET http://localhost:3000
組み込みミドルウェアを利用する方法
Expressフレームワークには組み込みのミドルウェアがあり、これらは特定の機能を提供します。例えば、以下のようなコードで静的ファイルを提供することができます。
builtin.js
const express = require('express');
const app = express();
// express.staticミドルウェアを使用して静的ファイルを提供する
app.use(express.static('public'));
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
解説
- Expressのインスタンスの作成
const express = require('express');
const app = express();
Expressモジュールをインポートし、そのインスタンスを作成します。
- 静的ファイルの提供
app.use(express.static('public'));
express.static
ミドルウェアを使用して、public
ディレクトリ内の静的ファイルを提供します。これにより、public
ディレクトリ内のファイルは、そのファイル名をパスとして直接アクセスできます。例えば、public
ディレクトリ内にsample.txt
というファイルがある場合、http://localhost:3000/sample.txt
というURLでその画像にアクセスできます。
- サーバーの起動
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
Expressのインスタンスをポート3000でリッスンさせ、サーバーを起動します。サーバーが起動したら、“Server is running on port 3000"というメッセージをコンソールに出力します。
テスト
curl -X GET http://localhost:3000/sample.txt
このコードは、public
ディレクトリ内の静的ファイルを提供します。例えば、ブラウザでhttp://localhost:3000/sample.txt
にアクセスすると、public/sample.txt
が表示されます。
サードパーティミドルウェアを利用する方法
Expressでは、NPMから利用可能なサードパーティのミドルウェアを利用することができます。例えば、以下のようなコードでmorgan
というログ出力用のミドルウェアを利用することができます。
まず、morgan
パッケージをプロジェクトにインストールします。
npm install morgan
次に、このパッケージをアプリケーションに組み込むためのコードを記述します。
thirdparty.js
const express = require('express');
const morgan = require('morgan');
const app = express();
// morganミドルウェアを使用してログを出力する
app.use(morgan('dev'));
app.get('/', (req, res) => {
res.send({ message: 'Hello, World!' });
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
解説
- ExpressとMorganのインスタンスの作成
const express = require('express');
const morgan = require('morgan');
const app = express();
ExpressとMorganモジュールをインポートします。そして、Expressのインスタンスを作成します。
- ログ出力の設定
app.use(morgan('dev'));
Morganミドルウェアを使用して、ログを出力します。ここでは、‘dev’フォーマットを使用しています。これにより、リクエストごとに短いレスポンスメッセージがコンソールに出力されます。
- ルートハンドラの定義
app.get('/', (req, res) => {
res.send({ message: 'Hello, World!' });
});
ルート(’/’)へのGETリクエストをハンドリングします。リクエストが来ると、‘Hello, World!‘というメッセージを含むJSONオブジェクトをレスポンスとして返します。
- サーバーの起動
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
Expressのインスタンスをポート3000でリッスンさせ、サーバーを起動します。サーバーが起動したら、“Server is running on port 3000"というメッセージをコンソールに出力します。
テスト
curl -X GET http://localhost:3000
このコードは、すべてのリクエストに対してmorgan
ミドルウェアが実行され、それによってHTTPリクエストの詳細がコンソールに出力されます。
エラーハンドリングミドルウェアの作成方法
エラーハンドリングミドルウェアは、他のミドルウェアから渡されたエラーを処理します。エラーハンドリングミドルウェアは、他のミドルウェアとは異なり、4つの引数(err
, req
, res
, next
)を取ります。以下はエラーハンドリングミドルウェアの作成例です。
errorhandling.js
const express = require('express');
const app = express();
app.get('/', (req, res) => {
throw new Error('Something went wrong');
});
// エラーハンドリングミドルウェア
app.use((err, req, res, next) => {
console.error(err.message);
res.status(500).send('Something went wrong');
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
解説
- Expressのインスタンスの作成
const express = require('express');
const app = express();
Expressモジュールをインポートし、そのインスタンスを作成します。
- ルートハンドラの定義
app.get('/', (req, res) => {
throw new Error('Something went wrong');
});
ルート(’/’)へのGETリクエストをハンドリングします。リクエストが来ると、エラーをスローします。
- エラーハンドリングミドルウェアの定義
app.use((err, req, res, next) => {
console.error(err.message);
res.status(500).send('Something went wrong');
});
エラーハンドリングミドルウェアを定義します。このミドルウェアは、エラーがスローされた場合に実行されます。エラーメッセージをコンソールに出力し、ステータスコード500とともにエラーメッセージをレスポンスとして送信します。
- サーバーの起動
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
Expressのインスタンスをポート3000でリッスンさせ、サーバーを起動します。サーバーが起動したら、“Server is running on port 3000"というメッセージをコンソールに出力します。
テスト
curl -X GET http://localhost:3000/
このコードでは、’/‘のルートにGETリクエストが来た時にエラーをスローします。このエラーはエラーハンドリングミドルウェアによってキャッチされ、エラーメッセージがコンソールに出力されます。また、クライアントに対しては500エラー(Internal Server Error)とともにエラーメッセージが返されます。