Можно ли объединить два ответа json с помощью nginx?

У меня есть существующая экспресс-конечная точка, которая выглядит так:

app.get(`${route}/:id`, async (req, res) => {
    try {
        const id = req.params.id;
        const result = await dbFn(id);
        res.send(result);
    } catch (err) {
        res.status(500).end();
    }
});

И это вернет объект, который выглядит так:

{
    "id": 123,
    "name": "Foo"
}

Теперь я хочу расширить этот API, чтобы, если он имеет заголовок Accept: application/vnd.v2, он также извлекал некоторые данные из другого сервиса и добавлял их. (См. мой связанный вопрос, где рекомендуется использовать согласование содержания).

т.е. ответ будет:

{
    "id": 123,
    "name": "Foo", 
    "extraData": {
        "foo": "bar"
    }
}

Теперь я могу сделать это с помощью экспресса, вот как я это сделал:

  app.get(`${route}/:id`, async (req, res, next) => {
    try {

      const id = req.params.id;
      const jobSeeker = await dbFn(id);
      if (req.accepts("application/vnd.v2")) {
        const response = await axios.get(`${integrationApiPath}/connection/${id}`); 
        const ssiData = response.data; 

        res.send({
          ...jobSeeker, 
          ssiData
        })

      }
      else {
        res.send(jobSeeker);
      }
    } catch (err) {
      res.status(500).end();
    }

  });

Но мне показалось, что это немного запутанный способ управления версиями API.

Что было бы намного лучше, так это если бы я мог вместо этого использовать nginx для обработки этого управления версиями.

Таким образом, мне не нужно изменять существующий API, я могу просто создать новую службу, а nginx проверит заголовки, вызовет оба микросервиса и соединит их вместе.

Это возможно?


person dwjohnston    schedule 01.05.2019    source источник


Ответы (1)


«Но мне показалось, что это немного запутанный способ управления версиями API». Я не думаю, что это плохой способ управления версиями API, поскольку это стандартный способ сделать это. Кроме того, вы можете обслуживать новую службу в новом подкаталоге (например, yourwebsite.com/yourservice.../v2/yourFunction).

«Было бы намного лучше, если бы вместо этого я мог использовать nginx для управления версиями». Я также не буду подтверждать, что было бы лучше позволить nginx выполнять «логику» вашего веб-сервиса, поскольку nginx собирается обслуживать ваш веб-сайт/веб-сервис и реализовывать логику.

Однако, если вы все еще хотите объединить запросы с помощью nginx, вы можете взглянуть на этот вопрос/ответ. В этом ответе используется openresty. Возможно, вам придется сначала установить это.

Как описано, вы можете вызывать несколько (в вашем случае 2) сервисов, используя этот код:

location /yourServiceV2 {
    content_by_lua_block {
        local respA = ngx.location.capture("/yourService")
        local respB = ngx.location.capture("/theServiceWhichExtendsYourService")

        ngx.say(respA.body .. respB.body)
    }
}

Если вы хотите выполнить указанный код только при наличии определенного заголовка, вы можете использовать оператор if, как описано в этот ответ. Итак, ваш оператор if будет выглядеть так:

if ($http_accept == 'application/vnd.v2') {
    return 405;
}
person Marvin Klar    schedule 03.05.2019
comment
Это будет выполнение A, а затем B, да? Это кажется строго хуже, чем делать это на уровне, на котором вы можете запускать эти запросы параллельно, я думаю. - person Alex Moore-Niemi; 20.11.2020
comment
Пример параллельного выполнения вышеуказанного: -multiple-ups" title="Есть ли способ настроить nginx для трансляции входящих запросов нескольким ИБП">stackoverflow.com/questions/22948017/ - person Alex Moore-Niemi; 21.11.2020