Expressの一部であるミドルウェアのご紹介

#はじめに
Node.jsのフレームワークである`Express`の機能であるミドルウェアについて`res, req, next`などの理解が少し足りていないのでアウトプットしたい気持ちが湧いてきたので今回は備忘録として執筆しました。

### 対象者

- Expressをさわったことがある方。
- これからExpressについて学習しようと思っている方。

## まず軽くExpressとは？
![express-facebook-share.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/924294/d2c30f50-ab28-a89e-4f78-5465ff898679.png)

冒頭でもふれたように2010年の11月にリリースされたNode.jsのWebフレームワークです。
主な特徴としては、http通信（メソッド）を利用するルーティング機能、`View`（画面）を手がけるテンプレートエンジンの使用

そして今回紹介する**ミドルウェア**の機能などがあります。

## ミドルウェア

そもそもの**ミドルウェアの役割**としては**アプリケーションとOS、それぞれの機能の中間を補佐してる**のがミドルウェアになります。
ちなみに...

- アプリケーションは、WordやExcel、動画・画像編集、様々なゲームなど
- OSは、コンピューターの制御・管理を担うソフトウェアのこと

と簡単に説明すると上記のような役割です。また、ミドルウェアには`Webサーバー`,`APサーバー`,`DBサーバー`の3種類ありそれらのサーバーの動作をするときにExpressを使用します。

# 📌ここから本題のExpress ミドルウェア

Expressでいう**ミドルウェア**とは、リクエスト（req）・レスポンス（res）を中心とした関数のことを指します。
ブラウザでの操作をしてhttpリクエストを送信時、Expressがブラウザからきたhttpリクエストを受け、何らかの処理を実行しレスポンスを返す。

つまり、**要求と応答の間で何らかの処理を実行する仕組み**をミドルウェアは担っています。

ちなみに下記の一連の流れがリクエストレスポンスサイクルになります。
ブラウザ入力 ⏩（リクエスト）⏩ **何らかの処理（Express）**⏩（レスポンス）⏩ ブラウザ出力

サイクルの処理を終了しない場合には、`next()`を使用して新たにミドルウェア関数を実装することができます。

大まかな説明は以上として、実際にタイプ別のミドルウェアについて説明していきます。
タイプはそれぞれ、`アプリケーション`、`ルーター`、`エラー処理`、`標準装備`があるので一つ一つ見ていきましょう。

## アプリケーションLevel

```javascript
var app = express(); //以下省略。

app.use(function (req, res, next) {
  console.log('Time:', Date.now());
  next()
});
```
`use()`を使用して、ミドルウェア関数を定義することができます。そして関数の引数`(req, res, next)`については以下の通りです。

- `req`：リクエストオブジェクト
- `res`：レスポンスオブジェクト
- `next`： 次のミドルウェア関数に処理を渡すコールバック関数

```javascript
app.use('/time',function (req, res, next) {
  res.send("Time");  
});
```

また上記のコードで、第一引数に`/time`を指定したので、`/time`にアクセスするたびに、ミドルウェアが実行されます。
`res.send()`でリクエストレスポンスサイクルを終了させ、`send()`を実行します。`send()`でテキストの表示。
`use()`以外にも、HTTPメソッド（GETやPOST）を使用してミドルウェアを実装できます。

## ルーターLevel

ルータレベルは、ルーターが複数ある時、個別にルーティングするために`express.Router()`を呼び、ミドルウェアを実装します。

```javascript
var router = express.Router();

router.get('/',function (req, res, next) {
  res.send('ホーム');
});

router.get('/hogehoge', function (req, res) {
  res.send('hogehoge');
});
```
Routerオブジェクトの`get()`を使用して`/`にアクセスした時に、テキスト（ホーム）が出力されます。hogehogeも同様。

## エラー処理Level

```javascript
app.get("/err", function (err, req, res, next) {
  console.log(err.status);
  if(err.status === 404) {
    res.send('ページが見つかりません。')
  }
});
```
`err, res, req, next`の四つの引数を使用して、エラー処理のミドルウェアを実装します。
`/err`へアクセスした時にエラーが発生した場合は、`err`引数を使用してステータス番号が404の場合は、「ページが見つかりません。」とテキストに表示されます。

## 標準装備Level

```javascript

// 静的ファイルの読み込み
app.use(express.static(path.join(__dirname, 'public')));

// jsonデータの読み込み・解析
app.use(express.json());

// URLエンコードの読み込み・解析
app.use(express.urlencoded());
```
Expressの標準として上記のミドルウェアの機能が組み込まれております。

#実装にあたって注意すること
```javascript
var express = require('express')
var app = express()

var myLogger = function (req, res, next) {
  console.log('LOGGED')
  next()
}

app.use(myLogger)

app.get('/', function (req, res) {
  res.send('Hello World!')
})

🚨
app.use(function (req, res, next) {
  console.log('Time:', Date.now());
  next()
});
🚨

app.listen(3000)
```
🚨で囲んだ箇所はミドルウェアとして実行されません。
前の`get()`のコールバック内で、`res`を使用しているのでリクエストレスポンスサイクルが終了してしまっているのためです。
なのでミドルウェアを実装する時は、サイクル内で処理が実行できるようにプログラムの順番を注意する必要があります。

#参考記事
[https://expressjs.com/ja/guide/using-middleware.html](https://expressjs.com/ja/guide/using-middleware.html)
[https://expressjs.com/ja/guide/writing-middleware.html](https://expressjs.com/ja/guide/writing-middleware.html)

#感想
expressの機能の一つであるミドルウェアは、MVCを構築する上でも必須になってくるので覚えておいて損はないと思い今回アウトプットしました。また、データベースを操作するORMの「Sequelize」についても学習していきたいっス。