我有以下用于后端的路由...
admin.js
router.get('/contents', ...); // GET /admin/contents
router.get('/:adminID', ...); // GET /admin/[adminID]
router.put('/:adminID', ...); // PUT /admin/[adminID]
router.get('/', ...); // GET /admin
router.post('/', ...); // POST /admin
..但是在测试中,以下内容:
PUT /admin/contents
触发PUT /admin/[adminID]
路线。但是“内容”不是ID。我知道为什么会发生这种情况(即符合模式),但是我不确定什么是最佳/通用的解决方案?理想情况下,我希望它认识到“内容”不是ID,实际上只是试图使用不可用的端点。
我可以使用类似...
router.use('/contents', require('./admin-contents'));
但是我宁愿将每个顶级端点限制为一个文件,而不是将其分散到这么多文件中。
在最坏的情况下,它将查找ID为“ contents”的管理员,并返回“找不到管理员”,但是我更希望它返回404,因为对于{{1 }}。
编辑#1
为明确起见,/admin
是字母和数字的组合,两者都出现在字符串的任何位置。正则表达式不起作用。
此外,adminID
的唯一路由是/admin/contents
。必须为所有其他方法(GET
,PUT
,PATCH
等)实现空白路由也不理想。
答案 0 :(得分:1)
为避免这种情况,您可以在路径中的参数项名称后提供regex
。
router.put('/:adminID(\\d+)', (req, res) => {
console.log(req.params.adminID); // I'm a number
});
现在adminID
必须是数字,否则它将不会输入路线。
虽然没有直接记录在express
routing上,但由于express使用path-to-regexp
,我们可以查看其相关文档:
它记录在Custom Matching Parameters
中const regexpNumbers = pathToRegexp('/icon-:foo(\\d+).png')
// keys = [{ name: 'foo', ... }]
regexpNumbers.exec('/icon-123.png')
//=> ['/icon-123.png', '123']
regexpNumbers.exec('/icon-abc.png')
//=> null
更新
您建议仅检查一个已知长度的数字 字符串应该起作用,
app.put('/:adminID((?:\\w+(?<=\\d+)(?:\\w+)?))', (req, res) => {
// I have at least 1 number
// I can have or not alpha-numeric characters
res.send(req.params.adminID);
});
正则表达式使用Postive lookbehind assertions
,自Node.js 9.11.2起就被支持,没有任何标志。因此,如果您使用的是旧版本,请升级或使用--harmony
标志运行它。
答案 1 :(得分:0)
您可以利用节点按顺序解释处理程序这一事实:
app.put('/admin/contents', (req, res) => res.send('contents'))
app.put('/admin/:adminId', (req, res) => res.send('id'))
当您输入admin/contents
时,将返回内容,对于其他任何URL admin/whatever
id 都将返回。