当您有子资源时,为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

哪些工作,但没有良好的资源/子资源格式。 这些groupsemployees团体,所以我希望url与之匹配。

如果我得到一个员工的组织,那么可以( /employees/:id/groups ),但是我得到所有组,这是员工组。

我怎么能设置快速路由正确的路由,同时仍然保持我想要的url结构..?

我想我需要一个快速的方式来区分一个id和一个子资源。 有没有办法做到这一点..?

UPDATE

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

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

快速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程,并在正确的时间发送响应。