使用 Express.js 嵌套路由器休息

新手上路,请多包涵

假设我想要大致如下所示的 REST 端点:

 /user/
/user/user_id

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

每个 if 上的 CRUD 都有意义。例如,/user POST 创建一个新用户,GET 获取所有用户。 /user/ user_id GET 只获取那个用户。

项目是特定于用户的,所以我将它们放在 user_id 下,这是一个特定的用户。

现在为了使 Express 路由模块化,我制作了一些路由器实例。用户有一个路由器,项目有一个路由器。

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

指向 item 的 URL 是 user 的 URL 层次结构的后代。现在我如何使用 /users 获取 URL 到 userRouter 但更具体的路由 /user/*user_id*/items/ 到 itemRouter?而且,如果可能的话,我希望 itemRouter 也可以访问 user_id。

原文由 huggie 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 811
2 个回答

您可以通过将路由器作为 中间件 附加到其他路由器上来嵌套路由器,无论是否使用 params

如果要从父路由器访问 params ,则必须将 {mergeParams: true} 传递给子路由器。

mergeParamsExpress 中引入 4.5.0 (2014 年 7 月 5 日)

在此示例中, itemRouter 附加到 userRouter/:userId/items 路由上

这将导致以下可能的路线:

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

原文由 Willem D‘Haeseleer 发布,翻译遵循 CC BY-SA 3.0 许可协议

可管理的嵌套路由…

我想要一个在 express 4 中以非常易于管理的方式执行嵌套路由的具体示例,这是“express 中的嵌套路由”的最高搜索结果。例如,这是一个 API,其中包含许多需要拆分的路由。

./index.js:

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

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

app.listen(3000);

./routes/api/index.js:

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

// split up route handling
router.use('/products', require('./products'));
router.use('/categories', require('./categories'));
// etc.

module.exports = router;

./routes/api/products.js:

 var router = require('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;

文件夹结构中的嵌套示例

我注意到一些关于“嵌套文件夹结构”的评论。这暗示了这一点,但并不明显,所以我添加了下面的部分。这是 routes 的嵌套文件夹结构 的具体示例。

 index.js
/api
  index.js
  /admin
    index.js
    /users
      index.js
      list.js
    /permissions
      index.js
      list.js

这是节点如何工作的更一般的例子。如果您在文件夹中使用“index.js”,类似于“index.html”在网页中用于默认目录的方式,这将很容易根据递归扩展您的组织,而无需更改您的代码入口点。 “index.js”是在目录中使用 require 时访问的默认文档。

index.js 的内容

const express = require('express');
const router = express.Router();
router.use('/api', require('./api'));
module.exports = router;

/api/index.js 的内容

const express = require('express');
const router = express.Router();
router.use('/admin', require('./admin'));
module.exports = router;

/api/admin/index.js 的内容

const express = require('express');
const router = express.Router();
router.use('/users', require('./users'));
router.use('/permissions', require('./permissions'));
module.exports = router;

/api/admin/users/index.js 的内容

const express = require('express');
const router = express.Router();
router.get('/', require('./list'));
module.exports = router;

这里可能存在一些 DRY 问题,但它确实有助于封装问题。

仅供参考,最近我进入了 actionhero 并发现它具有完整的功能 w/sockets 和任务,更像是一个真正的框架多合一翻转 REST 范式。你应该检查一下裸体 w/express。

原文由 King Friday 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题