【发布时间】:2017-10-23 21:12:10
【问题描述】:
我想为这些示例路由创建路由处理:
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
routes/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
routes/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
【问题讨论】:
-
您的组/用户文件中有什么?一个函数?您必须将函数传递给 router.use,例如如果您导出的组/用户文件中有一个函数 routing(),您将传递 Groups.routing 或调用它, function(req, res, next){ Groups.routing(req, res, next); }
-
两个路由器看起来非常相似:
express = require('express'); Users = require('../users'); router = express.Router(); router.get('/', function(req, res, next){}); router.get('/:groupid', function(req, res, next){}); router.use('/:groupid/users', Users); module.exports = router;还要注意 - 如果我没有周期性要求 - 就像 - 我使用users分组路由而不是groups路由在用户中,expressjs 处理得很好。 -
要求递归是行不通的。不过,您提供的错误消息并没有说明这一点。它更多的是错误的参数错误。因为您传递的不是函数,而是对象(路由器)
-
这听起来你需要将公共共享代码分解为共享函数并将它们放在自己的模块中,然后你的其他两个模块都可以加载共享模块并使用这些函数。使用 Express 编程时,人们似乎只将路由视为可共享单元,但您可以创建多个路由使用的通用函数,并将这些函数放在自己的模块中。
-
@jfriend00,
/users中调用的代码是Users.list(req, cb)方法。/users/:userid只需调用Users.find(req, cb)。与组路由相同(好吧,他们会调用Groups.list/find)。因此,如果路由是/users/:userid/groups,我想调用/groups调用的相同方法,在这种情况下Groups.list(req, cb)过滤具有成员:userid的组列表。/groups/:groupid/users也一样,我希望它调用/users调用的相同共享代码,属于:groupid的用户列表。