想象一下我想为微服务实现API网关。我在网关中有这种路由:
app.all('/api/users-service/*', (req, res, next) => {
});
我想做的是将req
转发给服务,却不知道它是GET
,POST
还是其他。我可能还需要构建两个不同的请求,将它们转发到两个不同的服务,然后在网关中返回合并的响应。像这样的东西:
app.all('/api/users-service/*', (req, res, next) => {
const user = await request(req, 'http://first-service/api/user/' + req.body.userId);
const products = await request(req, 'http://second-service/api/products');
res.status(200).json({
user: user,
products: products
});
});
我知道这是一个不好的例子,但希望您能理解我的尝试。
答案 0 :(得分:1)
您绝对可以将请求转发到其他服务,在某些情况下,代理正是您所需要的,而在其他情况下,您可能想做一些更复杂的事情,例如流程请求和响应。
在这种情况下,您可以尝试以下操作:
const rp = require("request-promise-native");
const bodyParser = require("body-parser");
const userServiceRootUrl = "http://first-service/api/user/";
const productServiceRootUrl = "http://second-service/api/products/";
app.all("/api/users-service/*", bodyParser.json(), async (req, res) => {
console.log("/api/users-service/ path:", req.params[0]);
const user = await rp({ baseUrl: userServiceRootUrl, url: req.params[0], body: req.body, json: true, method: req.method });
const products = await rp({ url: productServiceRootUrl });
res.status(200).json({
user: user,
products: products
});
});
在此示例中,我们使用request-promise-native,因为它为我们提供了基于Promise的api,您也可以使用node-fetch或其他一些http客户端。
在这种情况下,您还可以在快速服务器中创建模拟端点来测试响应处理,例如:
app.all("/api/user/*", bodyParser.json(), async (req, res) => {
console.log("/api/user/", req.path);
res.json( { name: "joe smith" })
});
app.all("/api/products/", bodyParser.json(), async (req, res) => {
console.log("/api/products/", req.path);
res.json( [{ id: 1, name: "some product" }]);
});
然后只需适当地更改userServiceRootUrl和productServiceRootUrl,例如
http://localhost:<port>/api/user/
http://localhost:<port>/api/products/