当您拥有子资源时,快速路由API - URL处理程序

时间:2016-05-04 15:40:58

标签: javascript node.js rest express

我有两个资源,员工和员工组。我试图实现一个很好的URL结构,如:

  • $('#student').on('change', function () { checkSubjects(); }); $('#student').on('keyup', function () { checkBoolean(); }); 列出员工。
  • GET /employees获得员工123。
  • GET /employees/123列出员工组。
  • GET /employees/groups获取员工组123。

使用ExpressJS我有:

GET /employees/groups/123

这不起作用,因为Express无法区分router.get('/employees', (req, res, next) => { next(); }); router.get('/employees/:id', (req, res, next) => { next(); }); router.get('/employees/groups', (req, res, next) => { next(); }); router.get('/employees/groups/:id', (req, res, next) => { next(); }); router.all('*', (req, res) => { res.send('...'); }); /employees/:id。它认为/employees/groupsgroups因为id是第一位的。

我确实有以下网址:

  • /employees/:id
  • GET /employees
  • GET /employees/123
  • GET /employees-groups

哪个有效,但没有好的资源/子资源格式。 GET /employees-groups/123groups的群组,因此我希望网址与之匹配。

如果我为一名员工获取这些组,那就没关系(employees),但我得到的是所有组,这些组是员工组。

如何在保持我想要的URL结构的同时设置Express路由以正确路由..?

我想Express需要一种方法来区分/employees/:id/groups和子资源。有没有办法做到这一点..?

更新

我显然应该说我在每个处理程序中使用id,因为我需要Express转移到另一个中间件函数,一个控制所有请求响应的函数。这是实际发送响应的其他中间件功能。所以我需要:

  1. 路线的处理程序。
  2. 处理所有请求。

2 个答案:

答案 0 :(得分:4)

快速搜索匹配的第一条路线并使用提供的功能处理它。

尝试相反的方式:

router.get('/employees', (req, res) => {});
router.get('/employees/groups', (req, res) => {});
router.get('/employees/groups/:id', (req, res) => {});
router.get('/employees/:id', (req, res) => {});

现在快递将通过路线,' / employees / 123'只会在最后一条路线上匹配,因此快递将使用一条路线。 ' /员工/组'将在第二条路线上尽快匹配,并且将使用该路线。

非常简单,但这些事情可能会花费你一些时间来搞清楚。

答案 1 :(得分:0)

RobbyD让我走上正轨。这就是我最终得到的结果:

index.js

router.all('*', setupHandler);
router.get('/employees', getEmployees);
router.get('/employees/groups', getGroups);
router.get('/employees/groups/:id', getGroup);
router.get('/employees/:id', getEmployee);
router.use(errorHandler);

setupHandler()

function setupHandler(req, res, next) {
    res.locals.standardRes = {
        "some": "data"
    };
    res.locals.doResponse = (res) => {
        // ...
        res.json(res.locals.standardRes);
    };
    next();
}

装getEmployees()

function getEmployees(req, res, next) {

    somethingThatReturnsAPromise().then(data => {
        // add to res.locals.standardRes here
        res.locals.doResponse(res);
    }).catch(err => {
        next(err);
    });

}

的ErrorHandler()

function errorHandler(err, req, res, next) {
    console.log('err', err);
    // add to res.locals.standardRes here
    // set correct res.status here
    res.locals.doResponse(res);
}

所以处理程序在RobbyD的答案中按顺序排列。我使用res.locals来保存响应函数(doResponse(res))以从每个处理程序调用。如果出现错误,我会正常致电next(err)以转移到errorHandler()

我想这一切都是为了从中间件到中间件获得正确的流程,并在合适的时间发送响应。