Rest with Express.js nested router

Suppose I want to have REST endpoints which look roughly like this:

/user/
/user/user_id 

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

CRUD on each if makes sense. For example, /user POST creates a new user, GET fetches all users. /user/user_id GET fetches just that one user.

Items are user specific so I put them under user_id, which is a particular user.

Now to make Express routing modular I made a few router instances. There is a router for user, and a router for the item.

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);

URL to item is descendents of the URL hierarchy of the user. Now how do I get URL with /users whatever to userRouter but the more specific route of /user/*user_id*/items/ to the itemRouter? And also, I would like user_id to be accessible to itemRouter as well, if possible.

You can nest routers by attaching them as middleware on an other router, with or without params.

You must pass {mergeParams: true} to the child router if you want to access the params from the parent router.

mergeParams was introduced in Express 4.5.0 (Jul 5 2014)

In this example the itemRouter gets attached to the userRouter on the /:userId/items route

This will result in following possible routes:

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 user');
    });

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 item 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);

var userRouter = require('express').Router();
var itemRouter = require('express').Router({ mergeParams: true }); 

userRouter.route('/')
  .get(function(req, res) {})
  .post(function(req, res) {})
userRouter.route('/:user_id')
  .get(function() {})

itemRouter.route('/')
  .get(function(req, res) {})
  .post(function(req, res) {})
itemRouter.route('/:item_id')
  .get(function(req, res) {
    return res.send(req.params);
  });

app.use('/user/', userRouter);
app.use('/user/:user_id/item', itemRouter);

The key to the second part of your question is the use of the mergeParams option

var itemRouter = require('express').Router({ mergeParams: true }); 

From /user/jordan/item/cat I get a reponse:

{"user_id":"jordan","item_id":"cat"}

The checked answer is quite sufficient but for me, I wanted a specific example of doing nested routes in a very manageable way in express 4 and this was the top search result for "nested routes in express". Here's an API that would have many routes that would need to be broken up for example.

./index.js:

var express = require('express');
var app = express();
var api = require('./routes/api');

// anything beginning with "/api" will go into this
app.use('/api', api);

app.listen(3000);

./routes/api/index.js:

var express = require('express');
var router = express.Router();

// split up route handling
var products = require('./products');
var categories = require('./categories');
// etc.

// list route namespaces
router.use('/products', products);
router.use('/categories', categories);
// etc.

module.exports = router;

./routes/api/products.js:

var express = require('express');
var router = express.Router();

// api/products
router.get('/', function(req, res) {
  res.json({ products: [] });
});

// api/products/:id
router.get('/:id', function(req, res) {
  res.json({ id: req.params.id });
});

module.exports = router;

You need only one router, and use it like this:

router.get('/users');
router.get('/users/:user_id');

router.get('/users/:user_id/items');
router.get('/users/:user_id/items/:item_id');

app.use('api/v1', router);