Expressにおけるミドルウェアとルーティング方法

[前回](https://qiita.com/kamihork/items/ba7d86b4933fb2071a6b)の続きになります。

# Expressにおけるミドルウェアとは
リクエスト / レスポンスのサイクルにおいて任意の処理を行う関数

## できること

- 任意コードの実行
- リクエストオブジェクト, レスポンスオブジェクトの変更
- リクエストレスポンスサイクルの終了
- スタック内の次のミドルウェアの呼び出し

## 定義

### 通常処理の場合

```javascript
function (req, res, next) {
    // 処理
    next();
}
```

### エラー処理の場合

```javascript
function (err, req, res, next){
    // 処理
    next();
}
```

## 利用方法

```javascript:app.js
// モジュールを利用
var express = require("express");
var app = express();

// app.useにミドルウェアを引き渡す
app.use((req, res, next) => {
    // 処理
});
```

## 実装例

リクエスト情報を取得したい場合。

```javascript:app.js
// moduleをrequire
var express = require("express");
var app = express();

// app.useにミドルウェアを引き渡す
app.use(require("./lib/logger.js"));
app.get("/", (req, res) => {
    res.status(200).send("Hello World");
});

// ポート指定でlisten
app.listen(3000);
```

```javascript:loger.js
module.exports = function (req, res, next) {
    // ipアドレス
    var ipaddress = req.headers["x-forwarded-for"] ||
        req.connection.remoteAddress ||
        (req.socket && req.socket.remoteAddress) ||
        (req.connection.socket && req.connection.socket.remoteAddress) ||
        "0.0.0.0";
    // 日付
    var date = (new Date()).toISOString();
    // リクエストメソッド
    var method = req.method;
    // リクエストURL
    var url = req.url;
    // リクエストユーザーーエージェント
    var ua = req.headers["user-agent"];
    // ログ出力
    console.log(`${ipaddress} [${date}] "${method} ${url}" - ${ua}` );
    // 次のミドルウェアを呼ぶ
    next();
};
```

ログに各パラメータが、ブラウザにはHello Wolrdが出力される。

# ルーティング
## 基本構文

```javascript
app.METHOD(PATH, CALLBACK)
```

- METHOD : リクエストメソッドを指定
- PATH : URLルーティングを指定
- CALLABCK : PATHにマッチした際の動作を指定

### 実装例

指定ルートでの挙動を書きたい場合。

```javascript:app.js
var express = require("express");
var app = express();

// 「/home/index」にマッチした場合の動作を指定
app.get("/home/index", (req, res) => {
    res.status(200).send("OK");
});

app.listen(3000);
```

[http://localhost:3000/home/index/](http://localhost:3000/home/index/)にアクセスし、ブラウザ上に「OK」と出力されればOK。

## パス設定について
名前付きパラメータを利用することで、URL中の値を分析してパラメータとして受け取ることができる。
また、正規表現を利用して記述することも可能。

### 実装例

```javascript:app.js
var express = require("express");
var app = express();

// 「/user/:id」にマッチした場合の動作を指定
app.get("/user/:id", (req, res) => {
    console.log(res.params.id);
    res.status(200).send("OK");
});

app.listen(3000);
```

[http://localhost:3000/12345/](http://localhost:3000/12345/)にアクセスし、ターミナル上に指定idが、ブラウザには「OK」が表示されればOK。


## Routingモジュール

webアプリケーションが大きくなる場合は、ルーティングのモジュール化を行い、管理を簡単にする。

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

### 実装例

例えば、共通ルートである/user/を外出ししたいような場合、以下のような処理となる。

```javascript:app.js
var express = require("express");
var app = express();

// 「/user」パスの配下の処理を記述
app.use("/user", require("./router/user.js"))

app.listen(3000);
```

```javascript:user.js
// ルーティングモジュールを呼び出し
var router = require("express").Router();

// routerに関わらず、アクセス日時を出力するミドルウェア
router.use((req, res, next) => {
    console.log((new Date()).toISOString());
    next();
});

// 「/user/」にマッチする場合の処理
router.get("/", (req, res) => {
    res.send("/user/");
});

// 「/user/about」にマッチする場合の処理
router.get("/about", (req, res) => {
    res.send("/user/about");
});

module.exports = router;
```



[http://localhost:3000/user/about](http://localhost:3000/user/about)にアクセスし、ターミナル上にアクセス日付が、ブラウザには「/user/about/」が表示されればOK。