ExpressJS,路由处理与两个路由器也使用对方?

我想为这些示例路由创build路由处理:

GET /users GET /users/:userid GET /users/:userid/groups GET /users/:userid/groups/:groupid GET /groups GET /groups/:groupid GET /groups/:groupid/users GET /groups/:groupid/users/:userid 

这个设置的代码示例。 设想一个目录结构如下:

 # index.js # routes/users.js # routes/groups.js # lib/users.js # lib/groups.js 

和每个内容是:

index.js

 express = require 'express' UsersRouter = require './routes/users' GroupsRouter = require './routes/groups' app = express() app.use '/users', UsersRouter app.use '/groups', GroupsRouter app.use (err, req, res, next) -> res.sendStatus(404) app.listen '3000', () -> console.log "Listening on port #{3000}" module.exports = app 

路线/ users.js

 express = require 'express' Users = require '../lib/users' GroupsRouter = require './groups' router = express.Router() router.param 'userid', (req, res, next, userid) -> req.userid = userid next() router.get '/', (req, res) -> Users.list req, (err, users) -> return next err if err res.status(200).send(users) router.get '/:userid', (req, res, next) -> Users.find req, (err, user) -> return next err if err res.status(200).send(user) router.use '/:userid/groups', GroupsRouter module.exports = router 

路线/ groups.js

 express = require 'express' Groups = require '../lib/groups' UsersRouter = require './users' router = express.Router() router.param 'groupid', (req, res, next, groupid) -> req.groupid = groupid next() router.get '/', (req, res, next) -> Groups.list req, (err, groups) -> return next err if err res.status(200).send(groups) router.get '/:groupid', (req, res, next) -> Groups.find req, (err, group) -> return next err if err res.status(200).send(group) router.use '/:groupid/users', UsersRouter module.exports = router 

LIB / users.js

 module.exports = list: (req, cb) -> if req.groupid return cb null, "List of all users in group #{req.groupid}" else return cb null, "List of all users" find: (req, cb) -> if req.groupid and req.userid return cb null, "User #{req.userid} if in #{req.groupid}" else return cb null, "The user #{req.userid}" 

LIB / groups.js

 module.exports = list: (req, cb) -> if req.userid return cb null, "List of all groups for #{req.userid}" else return cb null, "List of all groups" find: (req, cb) -> if req.userid and req.groupid return cb null, "Group #{req.groupid} if it has member #{req.userid}" else return cb null, "The group #{req.groupid}" 

问题是,我得到了一个espress.js错误做的路由器的周期性要求。 有没有可能做到这一点?

如果我只是在另一个路由器中包含一个路由器,反之亦然,它会从我的请求中得到预期的响应。

一个较长的路由用例的例子,比如说我想查看一个组中是否有一个用户,如果是这样的话,则返回所有其他用户所属的组:

 GET /groups/:groupid/users/:userid/groups 

我收到的错误:

 TypeError: Router.use() requires middleware function but got a Object 

users.js依赖于groups.js ,但是users.js在执行时会groups.js users.js 。 这意味着它将进入一个循环:

users.js调用groups.js

groups.js调用users.js ,它调用groups.js

这是解决这种循环情况的可能方法

将处理程序代码保存在单独的模块中,并在路由模块中重新使用。 (这是jfriend00在评论中也试图提出的观点)

例如。

 // userHandler.js module.exports = { browse: (req, res) => { // return user list }, find: (req, res) => { // return user } } // userRouter // ... const handler = require('userHandler'); router.get('/', handler.browse); // ... // groupsRouter // ... const uHandler = require('userHandler'); router.get('/:groupid/users', uHandler.browse); router.get('/:groupid/users/:userid', uHandler.find); // ... 

通过从一个路由器中导出一个中间件路由,我可以实现我想要的路由,我可以将其分配给我想要在另一个路由器中匹配的路由。

路线/ users.js

 express = require 'express' Users = require '../lib/users' router = express.Router() router.param 'userid', (req, res, next, userid) -> req.userid = userid next() router.pseudo = router.use (req, res, next) -> next() router.get '/', (req, res) -> Users.list req, (err, users) -> return next err if err res.status(200).send(users) router.get '/:userid', (req, res, next) -> Users.find req, (err, user) -> return next err if err res.status(200).send(user) module.exports = router router.use '/:userid/groups', (require '../groups').pseudo 

路线/ groups.js

 express = require 'express' Groups = require '../lib/groups' router = express.Router() router.param 'groupid', (req, res, next, groupid) -> req.groupid = groupid next() router.pseudo = router.use (req, res, next) -> next() router.get '/', (req, res, next) -> Groups.list req, (err, groups) -> return next err if err res.status(200).send(groups) router.get '/:groupid', (req, res, next) -> Groups.find req, (err, group) -> return next err if err res.status(200).send(group) module.exports = router router.use '/:groupid/users', (require '../users).pseudo 

这个路由设置允许像这样的请求:

 GET /groups/:groupid/users 

路由将从组路由中间件设置req.groupid值,然后路由到用户/路由列出用户。

同样的,如果你继续菊花链像他们一样:

 GET /groups/:groupid/users/:userid/groups 

路线将首先击中组,然后是用户,然后返回组,然后给我设置req.groupid和req.userid的值。