エンジニアを目指す日常ブログ

日々勉強したことのメモ。独学ですので間違っていたらコメント等で教えてください。

【Node.js+Express】ミドルウェアとapp.useについてメモ

はじめに

今回の記事の目的

Expressで利用される「ミドルウェア」と、ミドルウェアを呼び出すときに使われるapp.useについて調べたことをメモ。

前提

  • Node.jsとnpm(Node.jsのパッケージマネージャ)がインストールされていること。

tomiko0404.hatenablog.com

  • Node.js + Expessを利用してHTTPサーバを立ち上げていること。

前回の記事 tomiko0404.hatenablog.com

ミドルウェアとは

Expressの公式ページには以下の記載がある。

Express ミドルウェアの使用

Express は、それ自体では最小限の機能を備えたルーティングとミドルウェアの Web フレームワークです。Express アプリケーションは基本的に一連のミドルウェア関数呼び出しです。

そもそもExpressはミドルウェアの呼び出しという機能がメインなんです、という話のようである。

ミドルウェアは、以下のように関数で定義される。

( req, res, next) => {
 処理
 next();
}

app.send()の引数にする関数と同様で、reqはhttp.IncomingMessageクラスのインスタンスであり、resはhttp.ServerResponseクラスのインスタンスである。 nextは次のミドルウェアを呼び出す関数である。

また、エラー処理を行なうミドルウェアは、以下のように引数が4つとなる。

// エラー処理を行うミドルウェア
( err, req, res, next) => {
 処理
}

ミドルウェアを利用するapp.use

ミドルウェアの種類

ミドルウェアには以下の種類があるらしい。

アプリケーション・レベルのミドルウェアは、app.use()などのappオブジェクトで利用できる。

const express = require('express');
const app = express();
app.use( (req, res, next) => {
  処理
  next()
})

ルーター・レベルのミドルウェアは、routerオブジェクトで利用できる。(routerオブジェクトについては未勉強のため今回は省略する。)

const express = require('express');
const router = express.Router();
router.use((req,res,nest) => {
  処理
  next()
})

app.use()について

app.use()は、リクエストの種類にかかわらず実行される関数を定義できる。

公式の記載は以下の通り。

指定されたミドルウェア関数を指定されたパスにマウントします。ミドルウェア関数は、要求されたパスのベースがパスと一致したときに実行されます。 Express 4.x - API リファレンス

全てのリクエストに対し処理する場合の記載は以下。

app.use( (req, res, next) => {
    処理
}

パスを指定する場合の記載は以下。

app.use("[パス]", (req, res, next) => {
    処理
}

app.use()を使ってみる

パスの指定なし

以下のようにapp.jsを記載し実行してみる。

app.js

const express = require("express");
const portNumber = 8000;
const app = express();

app.use((req, res, next) => {
    console.log("パス指定無し");
    next();
});

app.get("/",(req,res)=>{
    res.status(200).send("Hello!")
})

app.listen(portNumber);
console.log(`PortNumber is ${portNumber}`);

実行し、GETメソッドでlocalhost:8000にリクエストすると以下のようコンソールに表示された。

$ node app.js
PortNumber is 8000
パス指定無し

ちなみに、next();を記載し忘れると、コンソールログは表示されるが、レスポンスはエラーとなった。

パスを指定する

app.use( "/sample" , メソッド)を利用し、localhost:8000/samplelocalhost:8000/sample/abcなど、sample以下のURLにアクセスした場合の処理を記載する。

app.js

const express = require("express");
const portNumber = 8000;
const app = express();

// どこにアクセスしても実行
app.use((req, res, next) => {
    console.log("パス指定無し");
    next();
});

// /sampleの配下にアクセスしたら実行
app.use("/sample", (req, res, next) => {
    console.log("/sampleへのアクセス");
    next();
});

// ルートフォルダにGETしたら実行
app.get("/", (req, res) => {
    res.status(200).send("Hello!");
});

// /sampleフォルダにGETしたら実行
app.get("/sample", (req, res) => {
    res.status(200).send("Hello! /sample");
});

// /sample/abcフォルダにGETしたら実行
app.get("/sample/abc", (req, res) => {
    res.status(200).send("Hello! /sample/abc");
});

app.listen(portNumber);
console.log(`PortNumber is ${portNumber}`);

この状態でlocalhost:8000/sample/abcにアクセスすると、以下のようにコンソールに表示された。

$ node app.js
PortNumber is 8000
パス指定無し
/sampleへのアクセス

パス指定なしのapp.useと、"/sample"を指定したapp.useの処理がどちらも実行されている。また、順序はソースコードで呼び出した順になっている。

ミドルウェアを外部呼出し場合

以下の記事で関数を外部から呼び出したように、ミドルウェア関数も呼び出すことができる。

tomiko0404.hatenablog.com

おわりに

今回はアプリケーション・レベルのミドルウェアを作成、利用することができた。