示例代码可在https://github.com/baumgarb/reverse-proxy-demo上找到:README.md解释了如果您克隆存储库,如何重现该问题。
我有一个API网关和一个返回服务的下游服务(TodosAPI)。客户端通过API网关访问下游服务。
API网关正在利用http-proxy-middleware
包来代理请求。有两种实现,第二种不起作用:
1。 main.ts
中的全局中间件,它在路径/ 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。已在应用模块中注册的nestMiddleware,该模块会在/ api / v2 / ...路径上启动
此方法对GET请求有效,但是其他http方法(如PUT)保持“挂起”状态,并且客户端上从未收到任何响应。问题似乎是从不调用下游服务中的控制器。 该中间件注册如下: nestMiddleware正在代理请求(我可以看到一条日志行显示 有人知道我在做什么错吗?提前非常感谢!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': ''
},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,\"title\": \"delectus aut autem - v2\",\"completed\": true}" http://localhost:8080/api/v2/todos-api/1
时遇到问题,即永远不会调用下游服务中的控制器[nestMiddleware]: Proxying PUT request originally made to '/api/v2/todos-api/1'...
),下游服务接收到该请求(我可以从日志记录中看到)。但是下游服务不会调用控制器/动作,并且最终永远不会返回。