ExpressJS,路由处理与两个也相互使用的路由器?

时间:2017-10-23 21:12:11

标签: node.js express

我想为这些示例路线创建路线处理:

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

3 个答案:

答案 0 :(得分:1)

users.js依赖于groups.js,但groups.js在执行时users.js需要users.js。这意味着它会循环:

groups.js来电groups.js

users.js调用groups.js来调用{{1}}等。

答案 1 :(得分:0)

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

将处理程序代码保存在单独的模块中,并在路径模块中重复使用。 (这是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);
// ...

答案 2 :(得分:0)

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

<强>路由/ users.js

Relay

<强>路由/ groups.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

此路由设置允许以下请求:

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

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

如果你继续用菊花链接它们就像:

/

该路线首先会击中群组,然后是用户,然后返回群组并为我提供req.groupid和req.userid的设定值。