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的值。