示例代码可在https://github.com/baumgarb/reverse-proxy-demo上找到。README.md 解释了如何在克隆存储库时重现问题。
我有一个 API 网关和一个返回 todos (TodosAPI) 的下游服务。客户端通过 API Gateway 访问下游服务。
API Gateway 正在利用http-proxy-middleware
包来代理请求。有两种实现,第二个不起作用:
main.ts
1.在路径 /api/v1/... 中启动的全局中间件
这种方法工作得很好,它代理所有对下游服务的请求,无论是什么 http 方法(GET、PUT、...)。
import * as proxy from 'http-proxy-middleware';
app.use(
'/api/v1/todos-api',
proxy({
target: 'http://localhost:8090/api',
pathRewrite: {
'/api/v1/todos-api': ''
},
secure: false,
onProxyReq: (proxyReq, req, res) => {
console.log(
`[Global Functional Middlware]: Proxying ${req.method} request originally made to '${req.originalUrl}'...`
);
}
})
);
2. 在路径 /api/v2/... 启动的应用程序模块中注册的 NestMiddleware
这种方法适用于 GET 请求,但其他 http 方法(如 PUT)一直“挂起”,并且客户端从未收到任何响应。问题似乎是下游服务中的控制器从未被调用。
import * as proxy from 'http-proxy-middleware';
export class ReverseProxyMiddleware implements NestMiddleware {
private proxy = proxy({
target: 'http://localhost:8090/api',
pathRewrite: {
'/api/v2/todos-api': ''
},
secure: false,
onProxyReq: (proxyReq, req, res) => {
console.log(
`[NestMiddleware]: Proxying ${req.method} request originally made to '${req.originalUrl}'...`
);
}
});
use(req: Request, res: Response, next: () => void) {
this.proxy(req, res, next);
}
}
而这个中间件注册如下:
@Module({
imports: [],
controllers: [AppController],
providers: [AppService]
})
export class AppModule implements NestModule {
configure(consumer: import('@nestjs/common').MiddlewareConsumer) {
consumer
.apply(ReverseProxyMiddleware)
.forRoutes({ path: 'v2/todos-api', method: RequestMethod.ALL });
}
}
- 跑步
curl -X PUT -H "Content-Type: application/json" -d "{\"id\": 1, \"userId\": 1, \"title\": \"delectus aut autem - v1\", \"completed\": true}" http://localhost:8080/api/v1/todos-api/1
效果很好 - 运行
curl -X PUT -H "Content-Type: application/json" -d "{\"id\": 1, \"userId\": 1, \"title\": \"delectus aut autem - v2\", \"completed\": true}" http://localhost:8080/api/v2/todos-api/1
中存在下游服务中的控制器永远不会被调用的问题
NestMiddleware 正在代理请求(我可以看到一条日志行[NestMiddleware]: Proxying PUT request originally made to '/api/v2/todos-api/1'...
),下游服务接收请求(我可以从日志中看到)。但是下游服务不会调用控制器/动作,最终永远不会返回。
有谁知道我在这里做错了什么?提前非常感谢!