コンパイラかく語りき

import { Fun } from 'programming'

Expressでルーティングをネストする際に、{mergeParams: true}でパラメータをマージする

まあ、タイトルの通りなんですが。小ネタです。

参照:Rest with Express.js nested router - stackoverflow.com

やりたいこと

ルーティングをネストしたい。 かつ、URL内にある:idをネストしたルーティングのどこからでも参照できるようにしたい。

userがあり、userに紐づくitemsがある。

/user/
/user/user_id 

/user/user_id/items/
/user/user_id/items/item_id

コード

結論(コード)から言うと以下のとおり。

const express = require('express')
const app = express()

const userRouter = express.Router()
const itemRouter = express.Router({mergeParams: true})

userRouter.use('/:userId/items', itemRouter)

userRouter.route('/')
    .get((req, res) => {
        res.status(200)
            .send('hello users')
    })

userRouter.route('/:userId')
    .get((req, res) => {
        res.status(200)
            .send('hello user ' + req.params.userId)
    })

itemRouter.route('/')
    .get((req, res) => {
        res.status(200)
            .send('hello items from user ' + req.params.userId)
    })

itemRouter.route('/:itemId')
    .get((req, res) => {
        res.status(200)
            .send('hello item ' + req.params.itemId + ' from user ' + req.params.userId);
    })

app.use('/user', userRouter)

app.listen(3000)

説明

express.Router() を2度使っている。1つがuserのルーティング用で、もう1つがitemsのルーティング用。

以下のコードで、useritemsをルーティング的に紐付けている

userRouter.use('/:userId/items', itemRouter)

express.Router([options]) - expressjs.com

また、ぶら下がる側のRouter()には、{mergeParams: true}を初期化時の引数として渡す。

const itemRouter = express.Router({mergeParams: true})

こうすることで、userreqだけでなく、itemsreqからもuserIdを参照できる。