Routerとは

ルーティング

URLパスとプログラム処理を対応させることをRouting(ルーティング)、URLマッピングなどといいます。ExpressのルーティングはRouterを利用するのが便利です。

Routerを利用しないデメリット

現状のサーバープログラムはルーティング処理を記述しているため、他のコードと混在してプログラムが膨大になり、管理しづらくなります。

server.js
const app = express();

//他の処理

app.get("/", (req, res) => {
    //処理
});

app.get("/profile", (req, res) => {
    //処理
});

app.post('/auth', (req, res) => {
    //処理
})

//他の処理

Routerのモジュール化

Routerを利用すると、ルーティング処理を外部モジュールとして別管理できます。

ルーティングファイル
const express = require('express');
// Routerオブジェクト生成
const router = express.Router();

// ルーティング設定
router.get("/", (req, res) => {
    //処理
});

// Routerを外部モジュール化
module.exports = router
  • module.exports で外部モジュール化

module.exportsとexportsとの違い

exportsmodule.exportsを参照しています。基本的に動作は同じですが、自体を新しいオブジェクトを作成するときは、module.exportsを利用します。

ミドルウェアで利用

作成したルーティングモジュールを、メインプログラムでミドルウェアに登録します。

server.js
const routes = require('./routes')

// Routerオブジェクトをミドルウェアに登録
app.use(routes)

Routerの利用

ファイル構成

express_sample/
├── data/
│   └── items.json
├── model/
│   └── item.js
├── node_modules/
├── .env
├── package-lock.json
├── package.json
├── public/
│   └── login.html
├── routes.js
└── server.js

パッケージ

パッケージ名 説明
express MVCフレームワーク
dotenv 設定ファイル管理モジュール
fs ファイルシステムアクセスモジュール

ルーティング

項目 URLパス HTTPメソッド
トップページ / GET
プロフィール /profile GET
ログイン認証 /auth POST
商品データ /item/{id} GET

Routerでルーティング

ルーティングファイル作成

プロジェクト内に、ルーティングファイル「routes.js」を作成します。

Router定義

express.Router() でオブジェクトを作成し、外部モジュール化します。

routes.js
// Expressモジュール読み込み
const express = require('express')
// Routerオブジェクト作成
const router = express.Router()
// Routerオブジェクトを外部モジュール化
module.exports = router

ルーティング移植

「server.js」のルーティング部分を「routes.js」に移植し、appの部分は routerに変更します。

routes.js
const express = require('express')
const router = express.Router()

// server.js からルーティング移植
// app を router に変更
router.get('/', (req, res) => {
    res.send('Hello Express Router!!')
})

router.get("/profile", (req, res) => {
    res.send("This is Profile page.");
})

router.post('/auth', (req, res) => {
    const login_name = req.body.login_name;
    const password = req.body.password;

    var message = 'ログインできませんでした';
    if (login_name == process.env.LOGIN_NAME && password == process.env.PASSWORD) {
        message = 'ログインしました';
    }
    res.send(message);
})

module.exports = router

ルーティング利用

「server.js」のミドルウェアで「routes.js」を利用します。 ルーティング部分がなくなったのでスッキリします。

server.js
const express = require('express')
// routes.js ファイルの読み込み
const routes = require('./routes')

const dotenv = require('dotenv');
dotenv.config();
const HOST = process.env.HOST
const PORT = process.env.PORT

const app = express()

app.use(express.urlencoded({ extended: true }))
app.use(express.static(__dirname + '/public'))

// Router をミドルウェアで処理
app.use(routes)

//ルーティング部分を削除

app.listen(PORT, HOST, () => {
    console.log(`Server listen: http://${HOST}:${PORT}`)
})

ルーティング確認

ホーム

http://localhost:3000/

プロフィール

http://localhost:3000/profile

ログイン認証

http://localhost:3000/login.html からPOST送信

データ表示処理

JSONファイルの商品データを読み込んで処理してみましょう。

データ読み込み準備

fs インストール

外部データを読み込むには「fs」モジュールを利用するため、「fs」モジュールをnpmインストールします。

ターミナル
npm i fs

JSONデータの用意

商品用のJSONデータ「data/items.json」を作成しておきます。

data/items.json
[
    { "id": 1, "name": "コーヒー", "price": 150 },
    { "id": 2, "name": "紅茶", "price": 180 },
    { "id": 3, "name": "ほうじ茶", "price": 100 }
]

商品モデル作成

商品モデルファイルで「fs」モジュールを読み込み、JSONファイルのパスを設定します。

models/item.js
const fs = require('fs');

//JSONファイルパス
exports.dataFile = "./data/items.json";

データ取得メソッド

データの全取得 get() と、ID検索 find() を追加します。

models/item.js
const fs = require('fs');
exports.dataFile = "./data/items.json";

// すべてのデータ読み込み
exports.get = () => {
    // JSONデータの読み込み&パース
    var values = JSON.parse(fs.readFileSync(this.dataFile, 'utf8'));
    return values
}

// idでデータ検索
exports.find = (id) => {
    var values = this.get()
    return values.find((value) => value.id == id)
}

プレースホルダー

プレースホルダーとは

プレースホルダー(Placeholder)は、文字列の特定の値や変数を取得するための記号のことで、URLパスから特定の値が利用できます。

https://example.com/users/:id

プレースホルダーの例

次のURLでは、:id がプレースホルダーとなり、パスパラメータの任意の値を取得できます。

URL
https://example.com/users/1
https://example.com/users/25

商品モデル読み込み

ルーティングファイルで商品モデルのモジュールを読み込んでおきます。

routes.js
const express = require('express');
const router = express.Router();

//商品モデルモジュール読み込み
const item = require('./models/item');
...

パスパラメーターの取得

ルーティング /item/ を追加し、:id をパスパラメータとします。

routes.js
router.get("/item/:id", (req, res) => {

})

パスパラメーター取得

リクエストオブジェクトのparamsから、パスパラメーター id を取得します。

routes.js
router.get("/item/:id", (req, res) => {
    // パスパラメーター id を取得
    const id = req.params.id
})

商品データの検索

id で商品検索し、メッセージをレスポンスします。

routes.js
router.get('/item/:id', (req, res) => {
    const id = req.params.id;
    //商品検索
    const selectItem = item.find(id);
    var message = '商品がみつかりませんでした';
    if (selectItem) {
        message = selectItem.name;
    }
    res.send(message);
})

商品データ表示確認

商品IDを指定して、ブラウザで確認してみましょう

ソース

server.js
const express = require('express');
const router = express.Router();

const item = require('./models/item');

router.get('/', (req, res) => {
    res.send('Hello Express Router!!');
})

router.get("/profile", (req, res) => {
    res.send("This is Profile page.");
})

router.post('/auth', (req, res) => {
    const login_name = req.body.login_name;
    const password = req.body.password;

    var message = 'ログインできませんでした';
    if (login_name == process.env.LOGIN_NAME && password == process.env.PASSWORD) {
        message = 'ログインしました';
    }
    res.send(message);
})

router.get('/item/:id', (req, res) => {
    const id = req.params.id;
    const selectItem = item.find(id);
    var message = '商品がみつかりませんでした';
    if (selectItem) {
        message = selectItem.name;
    }
    res.send(message);
})

module.exports = router

演習

問題1

Router/item/ のルーティングを追加してみましょう。

問題2

/item/ にアクセスしたら、商品名をブラウザですべて表示してみましょう。