Прокси-запросы, отличные от GET, зависают с NestJS и http-proxy-middleware - PullRequest
0 голосов
/ 06 ноября 2019

Пример кода доступен на 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, продолжают "висеть" и неответ когда-либо получен на клиенте. Кажется, проблема в том, что контроллер в нисходящем сервисе никогда не вызывается.

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'...) и нисходящий сервис получает запрос (я вижу это по логингу). Но нисходящий сервис не вызывает контроллер / действие и в конечном итоге никогда не возвращается.

Кто-нибудь знает, что я здесь не так делаю? Заранее большое спасибо!

...