Processamento de Solicitações em Lote com API Gateway

Bobur Umurzokov

Bobur Umurzokov

April 27, 2023

Technology

Processamento de solicitações em lote é uma técnica poderosa usada no desenvolvimento web para melhorar o desempenho de APIs. Ela permite que os desenvolvedores agrupem várias solicitações de API em um único ciclo de solicitação/resposta HTTP. Em outras palavras, uma única solicitação de API de um cliente pode ser transformada em múltiplas solicitações de API para um conjunto de servidores backend, e as respostas são agregadas em uma única resposta para o cliente. Isso pode reduzir significativamente o número de viagens de ida e volta entre o cliente e o servidor.

Neste artigo, exploraremos como implementar o processamento de solicitações em lote no Apache APISIX e veremos alguns casos de uso onde ele pode ser benéfico.

É semelhante ao padrão API Composition, que é amplamente aplicado na arquitetura de Microsserviços.

Processamento de solicitações em lote vs múltiplas chamadas de API

Por que usar o processamento de solicitações em lote?

Quando um cliente envia várias solicitações de API para um servidor, cada solicitação requer um ciclo de solicitação/resposta HTTP separado. Isso pode resultar em maior latência, desempenho reduzido e aumento da carga no servidor. Ao agrupar várias solicitações em uma única solicitação em lote, o número de ciclos de solicitação/resposta HTTP pode ser reduzido, resultando em melhor desempenho e menor latência.

O processamento de solicitações em lote pode ser particularmente útil em cenários onde você precisa recuperar ou atualizar vários registros em uma única transação, como:

  • Recuperar vários registros de um banco de dados
  • Atualizar vários registros em um banco de dados
  • Executar várias solicitações de API para concluir uma tarefa

Exemplos reais de processamento de solicitações em lote

Exemplo 1:

Suponha que você tenha um aplicativo de mídia social que exibe o feed de um usuário, que inclui postagens de seus amigos e páginas que ele segue. Para preencher esse feed, você precisa fazer várias solicitações de API para recuperar os dados necessários, como:

  • Recuperar uma lista dos amigos do usuário e das páginas que ele segue.
  • Para cada amigo ou página, recuperar suas postagens recentes.

Aplicativo de mídia social que exibe o feed de um usuário

Em uma abordagem tradicional, você realizaria cada uma dessas solicitações de API separadamente. Primeiro, você recuperaria uma lista de amigos do usuário e, na segunda solicitação, obteria as postagens recentes de cada amigo do usuário. Isso pode resultar em maior latência, especialmente quando o usuário tem um grande número de amigos e segue muitas páginas.

Exemplo 2:

Outro exemplo, você tem um aplicativo móvel que exibe uma lista de produtos para os usuários navegarem. Para preencher essa lista, você precisa fazer várias solicitações de API para recuperar dados de produtos de um servidor remoto, como:

  • Recuperar uma lista de IDs de produtos.
  • Para cada ID de produto, recuperar os detalhes do produto (nome, descrição, imagem, etc.)

Exemplo 3:

Imagine que você tem um aplicativo web para gerenciamento de conferências onde há vários palestrantes no sistema e você deseja exibir as sessões e tópicos relacionados de um palestrante em uma única página da web. Um serviço backend Conference API tem dois endpoints diferentes /speaker/{speakerId}/sessions e /speaker/{speakerId}/topics para expor essas informações. Para mostrar tanto as sessões quanto os tópicos pertencentes a um único palestrante, você pode enviar duas solicitações do aplicativo frontend, o que não é uma solução ideal. Em vez disso, você pode usar um API Gateway para agrupar todas essas solicitações em uma única solicitação HTTP, como explicado na próxima seção.

Processamento de solicitações em lote com API Gateway

Processamento de solicitações em lote com o API Gateway Apache APISIX

Para implementar o processamento de solicitações em lote no APISIX, você pode usar o plugin batch-requests. Esse plugin permite que você defina um conjunto de solicitações de API em um único payload de solicitação HTTP POST. Cada solicitação pode ter seu próprio método HTTP, caminho da URL, conjunto de cabeçalhos e payload. Veja um exemplo de comando curl para o exemplo 3 (solicitações da Conference API):

curl -i http://{API_GATEWAY_HOST_ADDRESS}/speaker  -X POST -d \
'{
    "pipeline": [
        {
            "method": "GET",
            "path": "/speaker/1/topics"
  },
        {
            "method": "GET",
            "path": "/speaker/1/sessions"
  }
    ]
}'

Quando uma solicitação em lote é recebida pelo APISIX, o plugin batch-requests analisará o payload e executará cada solicitação no lote em paralelo. O plugin também agregará as respostas de cada solicitação e as retornará em uma única resposta HTTP para o cliente. Veja a próxima seção de demonstração para aprender como alcançar isso passo a passo.

Demonstração do plugin de solicitações em lote

Antes de usar o plugin batch-requests, você precisará instalar o Apache APISIX.

Pré-requisitos

  • Docker é usado para instalar o etcd e o APISIX em contêineres.
  • curl é usado para enviar solicitações à API Admin do APISIX. Você também pode usar ferramentas fáceis como Postman para interagir com a API.

O APISIX pode ser facilmente instalado e iniciado com o seguinte script de início rápido:

curl -sL <https://run.api7.ai/apisix/quickstart> | sh

Configurar o serviço backend (upstream)

Você precisará configurar o serviço backend para a Conference API para o qual deseja rotear as solicitações. Isso pode ser feito adicionando um servidor upstream no Apache APISIX por meio da API Admin.

curl http://127.0.0.1:9180/apisix/admin/upstreams/1 -X PUT -d '
{
  "name": "Conferences API upstream",
  "desc": "Registrar a Conference API como o upstream",
  "type": "roundrobin",
  "scheme": "https",
  "nodes": {
    "conferenceapi.azurewebsites.net:443": 1
  }
}'

Criar uma Rota para a API de processamento em lote

Precisamos criar uma nova rota que intercepte solicitações para /speaker e exponha um endpoint virtual público para processamento em lote usando o plugin [public-api](https://apisix.apache.org/docs/apisix/plugins/public-api/).

curl http://127.0.0.1:9180/apisix/admin/routes/a -X PUT -d '
{
    "uri": "/speaker",
    "plugins": {
        "public-api": {
      "uri": "/apisix/batch-requests"
    }
    }
}'

Criar uma Rota para os endpoints de tópicos e sessões do palestrante

Em seguida, criamos outra rota para os endpoints de tópicos e sessões do palestrante (/speaker/*/topics e /speaker/*/sessions) para que as solicitações individuais extraídas pelo API Gateway das solicitações em lote para recuperar os tópicos ou sessões do palestrante sejam encaminhadas para os endpoints responsáveis da Conference API e referenciamos o serviço upstream existente.

curl http://127.0.0.1:9180/apisix/admin/routes/b -X PUT -d '
{
  "methods": ["GET"],
 "uris": ["/speaker/*/topics","/speaker/*/sessions"],
    "plugins": {
      "proxy-rewrite":{
      "host":"conferenceapi.azurewebsites.net"
  }
  },
 "upstream_id":"1"
}'

Você pode notar que estamos usando outro plugin proxy-rewrite e especificando implicitamente o endereço do host para a Conference API. Caso contrário, o API Gateway pode fazer a conversão DNS e solicitar a Conference API por seu endereço IP.

Testar o processamento de solicitações em lote

Aqui está um exemplo de como usar o plugin batch-requests no APISIX:

curl -i http://127.0.0.1:9080/speaker  -X POST -d \
'{
    "pipeline": [
        {
            "method": "GET",
            "path": "/speaker/1/topics"
  },
        {
            "method": "GET",
            "path": "/speaker/1/sessions"
  }
   ]
}'

Neste exemplo, a rota é definida para o endpoint /speaker, que suporta o processamento de solicitações em lote por meio do plugin batch-requests. O plugin é configurado com um conjunto de duas solicitações, cada uma recuperando um registro de palestrante por ID com tópicos e sessões. Se você executar este comando, receberá uma resposta mesclada do API Gateway:

[
   {
      "body":"{\r\n  \"collection\": {\r\n    \"version\": \"1.0\",\r\n    \"links\": [],\r\n    \"items\": [\r\n      {\r\n        \"href\": \"https://conferenceapi.azurewebsites.net/topic/8\",\r\n        \"data\": [\r\n          {\r\n            \"name\": \"Title\",\r\n            \"value\": \"Microsoft\"\r\n          }\r\n        ],\r\n        \"links\": [\r\n          {\r\n            \"rel\": \"http://tavis.net/rels/sessions\",\r\n            \"href\": \"https://conferenceapi.azurewebsites.net/topic/8/sessions\"\r\n          }\r\n        ]\r\n      },\r\n      {\r\n        \"href\": \"https://conferenceapi.azurewebsites.net/topic/10\",\r\n        \"data\": [\r\n          {\r\n            \"name\": \"Title\",\r\n            \"value\": \"Mobile\"\r\n          }\r\n        ],\r\n        \"links\": [\r\n          {\r\n            \"rel\": \"http://tavis.net/rels/sessions\",\r\n            \"href\": \"https://conferenceapi.azurewebsites.net/topic/10/sessions\"\r\n          }\r\n        ]\r\n      }\r\n    ],\r\n    \"queries\": [],\r\n    \"template\": {\r\n      \"data\": []\r\n    }\r\n  }\r\n}",
      "status":200,
      "headers":{
         "Expires":"-1",
         "Connection":"keep-alive",
         "Pragma":"no-cache",
         "Content-Length":"953",
         "Server":"APISIX/3.2.0",
         "Content-Type":"application/vnd.collection+json",
         "X-AspNet-Version":"4.0.30319",
         "Cache-Control":"no-cache",
         "X-Powered-By":"ASP.NET"
      },
      "reason":"OK"
   },
   {
      "body":"{\r\n  \"collection\": {\r\n    \"version\": \"1.0\",\r\n    \"links\": [],\r\n    \"items\": [\r\n      {\r\n        \"href\": \"https://conferenceapi.azurewebsites.net/session/206\",\r\n        \"data\": [\r\n          {\r\n            \"name\": \"Title\",\r\n            \"value\": \"\\r\\n\\t\\t\\tjQuery Mobile and ASP.NET MVC\\r\\n\\t\\t\"\r\n          },\r\n          {\r\n            \"name\": \"Timeslot\",\r\n            \"value\": \"05 December 2013 09:00 - 10:00\"\r\n          },\r\n          {\r\n            \"name\": \"Speaker\",\r\n            \"value\": \"Scott Allen\"\r\n          }\r\n        ],\r\n        \"links\": [\r\n          {\r\n            \"rel\": \"http://tavis.net/rels/speaker\",\r\n            \"href\": \"https://conferenceapi.azurewebsites.net/speaker/16\"\r\n          },\r\n          {\r\n            \"rel\": \"http://tavis.net/rels/topics\",\r\n            \"href\": \"https://conferenceapi.azurewebsites.net/session/206/topics\"\r\n          }\r\n        ]\r\n      }\r\n    ],\r\n    \"queries\": [],\r\n    \"template\": {\r\n      \"data\": []\r\n    }\r\n  }\r\n}",
      "status":200,
      "headers":{
         "Expires":"-1",
         "Connection":"keep-alive",
         "Pragma":"no-cache",
         "Content-Length":"961",
         "Server":"APISIX/3.2.0",
         "Content-Type":"application/vnd.collection+json",
         "X-AspNet-Version":"4.0.30319",
         "Cache-Control":"no-cache",
         "X-Powered-By":"ASP.NET"
      },
      "reason":"OK"
   }
]

O tamanho máximo de uma solicitação em lote é limitado pelo API Gateway. Você pode verificar a documentação do API Gateway para os limites atuais e a configuração de tempo limite de solicitação.

Conclusões

  • O processamento de solicitações em lote com API Gateway pode ser uma técnica útil para melhorar o desempenho da sua API.
  • O Apache APISIX fornece um plugin chamado batch-requests que permite que os desenvolvedores implementem o processamento de solicitações em lote com facilidade.

Próximos passos

Com o API Gateway, também é possível fornecer alguma forma de agregação personalizada nos dados de resposta para seus usuários. Você pode usar o plugin serverless-function para executar código personalizado e mesclar a resposta dos serviços backend e retorná-la ao consumidor da API em uma estrutura diferente.

Conteúdo recomendado

Tags: