⚙️

Expressのミドルウェアとは何か

2024/03/24に公開

Expressを学習し始めて、最初に疑問に思ったのが「ミドルウェア」でした。
備忘録も兼ねて簡単にまとめます📝

Expressとは

Node.jsのためのフレームワークです。
アプリケーション開発用で、シンプルかつ柔軟性の高い機能を提供し、REST API開発も容易にしてくれます。
https://expressjs.com/ja/

ルーティング

Expressではクライアントからある特定のリクエストがあった場合に、どのようなレスポンスを返すかを設定します。これが「ルーティング」です。
下記の例のように、POSTやGETなどのHTTPリクエストメソッドとURI(パス)を設定し、そのリクエストに対してどんな処理を行うのかを決めます。
ちなみにPOSTやGETのほか、PUT、DELETEなどがあります。

// GET
app.get("/", (req, res) => {
  res.render("homepage");
});

// POST
app.post("/", (req, res) => {
  res.send("POST request to the homepage");
});

ミドルウェアとは

ミドルウェアとは単なる関数のことです。
上記のルーティングの例のように、リクエストが送られレスポンスが返されるというサイクルの間に実行できる関数が「ミドルウェア」です。
下記のようにres.send()などのメソッドでレスポンスを返し、HTTPリクエストを終了させます。

// 基本形
app.use((req, res, next) => {
  res.send("Hello World");
});

ミドルウェアのnext()について

ミドルウェアは引数にnextを受け取り、next()を呼び出すことで次に設定したミドルウェアを実行します。
下記の例では
1️⃣1番目のミドルウェアで、next()を呼び出す
2️⃣2番目のミドルウェアの処理を実行
の順番で処理が実行されます。

注意するポイントとして、next()でreturnを指定していない場合は、1番目のミドルウェアのnext()以降に書いた処理が実行されます。

app.use((req, res, next) => {
	console.log("1番目のミドルウェア");
	return next(); // returnで以降の処理が走らないように終わらせる。
	console.log("1番目のミドルウェアのnext()以降に実行");
});

app.use((req, res,next) => {
	console.log("2番目のミドルウェア");
	return next();
});

// log
// 1番目のミドルウェア
// 2番目のミドルウェア

またミドルウェア機能は記載した順番に実行されるため、組み込む順序も重要です。
下記のようにnext()が指定されていないミドルウェアの後にGETメソッドを書いてしまうと、走らなくなってしまいます。

// next()を呼び出していないミドルウェア
app.use((req, res, next) => {
  res.send("Hello World");
});

// この処理は実行されない
app.get("/", (req, res) => {
  res.send("Welcome");
});

使いどころ

全体または複数のリクエストで共通で使用する処理がある場合、それを1つのミドルウェアとして作成しておくと、何度も記載しなくていいので便利です。

例えばフォームが複数あるアプリケーションなどで、共通して必要なバリデーション処理がある場合、バリデーション処理をミドルウェアとして定義しておきます。
次に各リクエストメソッドにて定義したミドルウェアを挟み込みます。

// ミドルウェア
const validateForms = (req, res, next) => {
  // 実行させたいバリデーション処理を記述
  next();
};

// POSTメソッドでフォームの値を送信する時にバリデーション(ミドルウェア)を行ってから実行する
app.post("/", validateForms, (req, res) => {
  res.send("フォームを送信しました。");
});

参考URL

Discussion