手动呼叫Express路由器
Нello!我想调用一个已传递给expressRouter.post(...)
调用的函数。
这个expressRouter.post(...)
调用发生在我无法修改的文件中。代码已经分发给许多客户端,我没有程序可以修改他们的文件版本。虽然我无法为远程客户端更新此文件,但其他开发人员可以。因此,我面临着POST端点的行为在将来发生变化的问题。
我也在处理性能问题。此POST端点要求req.body
是已解析的JSON对象,并且该JSON对象可能过大。
我的目标是编写一个GET端点,在内部激活此POST端点。 GET端点需要使用非常大的JSON值调用POST端点,该端点已插入URL查询参数。 GET的功能应始终反映POST的功能,包括将来更新POST的功能。因此我无法复制/粘贴POST的逻辑。另请注意,JSON格式永远不会更改。
我理解在内部调用expressjs端点的问题通常由1)extracting the router function into an accessible scope或2)generating an HTTP request to localhost解决。
不幸的是,就我而言,这些选项都不可行:
- 我无法将函数移动到可访问的范围内,因为我无法修改源代码,也无法复制粘贴函数,因为原始版本可能会更改
- 出于性能考虑,避免HTTP请求是一个高优先级。 HTTP请求将需要序列化+反序列化过大的JSON主体,重新访问许多身份验证中间件(需要等待进一步的HTTP请求+数据库查询才能完成),等等
这是我的(人为的)POST端点:
expressRouter.post('/my/post/endpoint', (req, res) => {
if (!req.body.hasOwnProperty('val'))
return res.status(400).send('Missing "val"');
return res.status(200).send(`Your val: ${req.body.val}`);
});
如果我向localhost:<port>/my/post/endpoint
发出POST请求,我会根据是否在JSON正文中包含“val”来获得预期的错误或响应。
现在,我想拥有完全相同的功能,但是通过GET,并在URL中提供“val”,而不是在任何JSON主体中。我尝试过以下方法:
expressRouter.get('/my/get/endpoint/:val', (req, res) => {
// Make it seem as if "val" occurred inside the JSON body
let fakeReq = {
body: {
val: req.params.val
}
};
// Now call the POST endpoint
// Pass the fake request, and the real response
// This should enable the POST endpoint to write data to the
// response, and it will seem like THIS endpoint wrote to the
// response.
manuallyCallExpressEndpoint(expressRouter, 'POST', '/my/post/endpoint', fakeReq, res);
});
不幸的是我不知道如何实施manuallyCallExpressEndpoint
。
是否有解决此问题的方法,该方法不包括将函数提取到可访问的范围,以及生成HTTP请求?
回答如下:简单的中间件怎么样?
function checkVal(req, res, next) {
const val = req.params.val || req.body.val
if (!val) {
return res.status(400).send('Missing "val"');
}
return res.status(200).send(`Your val: ${val}`);
}
app.get('/my/get/endpoint/:val', checkVal)
app.post('/my/post/endpoint', checkVal)
此代码未经过测试,但您可以大致了解如何在两个位置运行相同的代码。
checkVal函数用作Express处理程序,包含请求,响应和下一个。它首先检查params然后检查身体。