当您有子资源时,为API – URL处理程序快速路由
我有两个资源,员工和员工组。 我试图实现一个漂亮的URL结构,如:
-
GET /employees
列出员工。 -
GET /employees/123
获取员工123。 -
GET /employees/groups
列出员工组。 -
GET /employees/groups/123
获取员工组123。
使用ExpressJS我有:
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('...'); });
这是行不通的,因为Express不能区分/employees/:id
和/employees/groups
。 它认为groups
是一个id
因为/employees/:id
是第一位的。
我确实有URL:
-
GET /employees
-
GET /employees/123
-
GET /employees-groups
-
GET /employees-groups/123
哪些工作,但没有良好的资源/子资源格式。 这些groups
是employees
团体,所以我希望url与之匹配。
如果我得到一个员工的组织,那么可以( /employees/:id/groups
),但是我得到所有组,这是员工组。
我怎么能设置快速路由正确的路由,同时仍然保持我想要的url结构..?
我想我需要一个快速的方式来区分一个id
和一个子资源。 有没有办法做到这一点..?
UPDATE
我显然应该说我在每个处理程序中都使用next()
,因为我需要Express来转移到另一个中间件函数,它控制所有请求的响应。 这是其他中间件function,实际上发送一个响应。 所以我需要:
- 处理器的路线。
- 处理所有请求。
快速search匹配的第一条路线,并使用提供的function处理它。
尝试另一种方式:
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'将只匹配最后一个路线,以便快递使用。 '/ employees / groups'将会在第二条路线上更早地匹配,并且那个将被使用。
非常简单,但这些东西可能花费你一些时间搞清楚。
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()
。
我想所有关于从中间件到中间件的正确stream程,并在正确的时间发送响应。