Odpočívejte s vnořeným routerem Express.js

Předpokládejme, že chci mít koncové body REST, které vypadají zhruba takto:

/user/
/user/user_id 

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

CRUD na každém, pokud to dává smysl. Například /user POST vytvoří nového uživatele, GET načte všechny uživatele. /user/id_uživatele GET načte právě tohoto jednoho uživatele.

Položky jsou specifické pro uživatele, proto jsem je umístil pod user_id , což je konkrétní uživatel.

Nyní, aby bylo expresní směrování modulární, vytvořil jsem několik instancí směrovače. K dispozici je router pro uživatele a router pro položku.

var userRouter = require('express').Router();
userRouter.route('/')
  .get(function() {})
  .post(function() {})
userRouter.route('/:user_id')
  .get(function() {})

var itemRouter = require('express').Router();
itemRouter.route('/')
  .get(function() {})
  .post(function() {})
itemRouter.route('/:item_id')
  .get(function() {})

app.use('/users', userRouter);

// Now how to add the next router?
// app.use('/users/', itemRouter);

Adresa URL do item je potomky hierarchie URL user . Jak nyní získám adresu URL s /users cokoliv k userRouter, ale specifičtější cesta /user/*user_id*/items/ k položceRouter? A také bych chtěl, aby user_id bylo přístupné také pro itemRouter, pokud je to možné.

Odpověď

Směrovače můžete vnořit tak, že je připojíte jako middleware k jinému směrovači, s nebo bez params .

Musíte projít {mergeParams: true} k podřízenému routeru, pokud chcete přistupovat k params z nadřazeného routeru.

mergeParams byl představen v Express 4.5.0 (5. července 2014)

V tomto příkladu itemRouter se připojí k userRouter na /:userId/items trasa

Výsledkem budou následující možné trasy:

GET /user -> hello user
GET /user/5 -> hello user 5
GET /user/5/items -> hello items from user 5
GET /user/5/items/6 -> hello item 6 from user 5

var express = require('express');
var app = express();

var userRouter = express.Router();
// you need to set mergeParams: true on the router,
// if you want to access params from the parent router
var itemRouter = express.Router({mergeParams: true});

// you can nest routers by attaching them as middleware:
userRouter.use('/:userId/items', itemRouter);

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

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

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

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

app.use('/user', userRouter);

app.listen(3003);