我有两个资源,员工和员工组。我试图实现一个很好的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/groups
是groups
因为id
是第一位的。
我确实有以下网址:
/employees/:id
GET /employees
GET /employees/123
GET /employees-groups
哪个有效,但没有好的资源/子资源格式。 GET /employees-groups/123
是groups
的群组,因此我希望网址与之匹配。
如果我为一名员工获取这些组,那就没关系(employees
),但我得到的是所有组,这些组是员工组。
如何在保持我想要的URL结构的同时设置Express路由以正确路由..?
我想Express需要一种方法来区分/employees/:id/groups
和子资源。有没有办法做到这一点..?
更新
我显然应该说我在每个处理程序中使用id
,因为我需要Express转移到另一个中间件函数,一个控制所有请求响应的函数。这是实际发送响应的其他中间件功能。所以我需要:
答案 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让我走上正轨。这就是我最终得到的结果:
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);
function setupHandler(req, res, next) {
res.locals.standardRes = {
"some": "data"
};
res.locals.doResponse = (res) => {
// ...
res.json(res.locals.standardRes);
};
next();
}
function getEmployees(req, res, next) {
somethingThatReturnsAPromise().then(data => {
// add to res.locals.standardRes here
res.locals.doResponse(res);
}).catch(err => {
next(err);
});
}
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()
。
我想这一切都是为了从中间件到中间件获得正确的流程,并在合适的时间发送响应。