Chaining API Requests with API Gateway
May 23, 2023
À medida que o número de APIs que precisam ser integradas aumenta, gerenciar a complexidade das interações com APIs torna-se cada vez mais desafiador. Ao usar o API Gateway, podemos criar uma sequência de chamadas de API, o que divide os fluxos de trabalho de API em etapas menores e mais gerenciáveis. Por exemplo, em um site de compras online, quando um cliente pesquisa por um produto, a plataforma pode enviar uma solicitação para a API de busca de produtos e, em seguida, enviar uma solicitação para a API de detalhes do produto para obter mais informações sobre os produtos. Neste artigo, criaremos um plugin personalizado para o Apache APISIX API Gateway para lidar com solicitações de clientes que devem ser chamadas em sequência.
Objetivos de aprendizagem
Você aprenderá o seguinte ao longo do artigo:
- O que são solicitações de API encadeadas?
- Exemplo de chamadas de API sequenciais.
- Como construir um plugin personalizado de pipeline-request para o Apache APISIX.
- Demonstração do plugin pipeline-request.
O que é uma solicitação de API encadeada e por que precisamos dela?
Solicitações de API encadeadas (ou solicitações em pipeline, ou chamadas de API sequenciais) são uma técnica usada no desenvolvimento de software para gerenciar a complexidade das interações com APIs, onde o software requer múltiplas chamadas de API para concluir uma tarefa. É semelhante ao processamento de solicitações em lote, onde você agrupa várias solicitações de API em uma única solicitação e as envia ao servidor como um lote. Embora possam parecer semelhantes, uma solicitação em pipeline envolve o envio de uma única solicitação ao servidor que dispara uma sequência de solicitações de API para serem executadas em uma ordem definida. Cada solicitação de API na sequência pode modificar os dados da solicitação e da resposta, e a resposta de uma solicitação de API é passada como entrada para a próxima solicitação de API na sequência. As solicitações em pipeline podem ser úteis quando um cliente precisa executar uma sequência de solicitações de API dependentes que devem ser executadas em uma ordem específica.
Em cada etapa do pipeline, podemos transformar ou manipular os dados da resposta antes de passá-los para a próxima etapa. Isso pode ser útil em situações onde os dados precisam ser normalizados ou transformados ou filtrar dados sensíveis antes de serem retornados ao cliente. Isso pode ajudar a reduzir a latência geral. Por exemplo, uma chamada de API pode ser feita enquanto outra está aguardando uma resposta, reduzindo o tempo total necessário para concluir o fluxo de trabalho.
Plugin personalizado de pipeline-request para Apache APISIX
Um API gateway pode ser o local certo para implementar essa funcionalidade, pois pode interceptar todas as solicitações do aplicativo cliente e encaminhá-las para os destinos pretendidos. Vamos usar o Apache APISIX, pois é uma solução de API Gateway de código aberto popular com uma série de plugins integrados. No entanto, no momento do desenvolvimento deste post, o APISIX não tinha suporte oficial para o plugin de pipeline-request. Com o conhecimento das capacidades de desenvolvimento de plugins personalizados do APISIX, decidimos introduzir um novo plugin que pode oferecer a mesma funcionalidade. Há um repositório no GitHub com o código-fonte escrito na linguagem de programação Lua e uma descrição do plugin pipeline-request.
Com este plugin, você pode especificar uma lista de APIs upstream que devem ser chamadas em sequência para lidar com uma única solicitação do cliente. Cada API upstream pode modificar os dados da solicitação e da resposta, e a resposta de uma API upstream é passada como entrada para a próxima API upstream no pipeline. O pipeline pode ser definido em uma configuração de Rota, e você também pode definir ordens para URLs de API quando o pipeline deve executá-las.
Vamos entender o uso deste plugin com um exemplo. Suponha que você tenha duas APIs - uma que faz solicitações GET /credit_cards
para recuperar informações de cartão de crédito e outra que recebe os dados da resposta anterior no corpo da solicitação POST /filter
e, em seguida, filtra os dados sensíveis (como o número do cartão de crédito e a data de validade) antes de retornar a resposta ao cliente. Como o endpoint da API de cartão de crédito retorna informações sensíveis que não devem ser expostas a partes não autorizadas. O diagrama abaixo ilustra o fluxo geral de dados:
- Quando um cliente faz uma solicitação ao endpoint da API de cartão de crédito do API Gateway para recuperar todas as informações do cartão de crédito, o API Gateway encaminha uma solicitação para recuperar os dados do cartão de crédito do serviço backend de cartão de crédito.
- Se a solicitação for bem-sucedida e retornar os dados do cartão de crédito, eles são passados para a próxima etapa no pipeline, que é o serviço de segurança.
- Quando a resposta filtrada é recebida do serviço de segurança, ela retorna a resposta combinada ao cliente.
Demonstração do plugin pipeline-request
Para esta demonstração, vamos aproveitar outro projeto de demonstração preparado no GitHub, onde você pode encontrar todos os exemplos de comandos curl usados neste tutorial, executar o APISIX e habilitar um plugin personalizado sem configuração adicional com um arquivo Docker compose.yml.
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.
Passo 1: Instalar e executar o APISIX e o etcd
Você pode instalar facilmente o APISIX e o etcd executando docker compose up
na pasta raiz do projeto após fazer fork/clone do projeto. Você pode notar que há um volume ./custom-plugins:/opt/apisix/plugins:ro
especificado no arquivo docker-compose.yml
. Isso monta o diretório local ./custom-plugins
, onde nosso arquivo pipeline-request.lua
com a implementação do plugin personalizado está localizado, como um volume somente leitura no contêiner docker no caminho /opt/apisix/plugins
. Isso permite que plugins personalizados sejam adicionados ao APISIX em tempo de execução (essa configuração só é aplicável se você executar o APISIX com docker).
Passo 2: Criar a primeira Rota com o plugin pipeline-request
Assim que o APISIX estiver em execução, usamos o comando cURL que é usado para enviar uma solicitação HTTP PUT para o endpoint /routes
da API Admin do APISIX para criar nossa primeira rota que escuta o caminho URI /my-credit-cards
.
curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/1' \
--header 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
--header 'Content-Type: application/json' \
--data-raw '{
"uri":"/my-credit-cards",
"plugins":{
"pipeline-request":{
"nodes":[
{
"url":"https://random-data-api.com/api/v2/credit_cards"
},
{
"url":"http://127.0.0.1:9080/filter"
}
]
}
}
}'
A parte importante da configuração é a seção "plugins", que especifica que o plugin "pipeline-request" deve ser usado para esta rota de API. A configuração do plugin contém um array "nodes", que define a sequência de solicitações de API que devem ser executadas no pipeline. Você pode definir uma ou várias APIs lá. Neste caso, o pipeline consiste em dois nós: o primeiro nó envia uma solicitação para a API https://random-data-api.com/api/v2/credit_cards para recuperar os dados do cartão de crédito, e o segundo nó envia uma solicitação para uma API local em http://127.0.0.1:9080/filter para filtrar os dados sensíveis das informações do cartão de crédito. A segunda API será apenas uma função serverless usando o plugin serverless-pre-function do APISIX. Ela atua apenas como um serviço backend para modificar a resposta da primeira API.
Passo 3: Criar a segunda Rota com o plugin serverless
Em seguida, configuramos uma nova rota com o ID 2 que lida com solicitações ao endpoint /filter
no pipeline. Ele também habilita o plugin serverless-pre-function existente do APISIX, onde especificamos uma função Lua que deve ser executada pelo plugin. Esta função simplesmente recupera o corpo da solicitação da resposta anterior, substitui o campo do número do cartão de crédito e deixa o restante da resposta inalterado. Finalmente, define o corpo da resposta atual para o corpo da solicitação modificado e envia uma resposta HTTP 200 de volta ao cliente. Você pode modificar este script para atender às suas necessidades, como usar o corpo decodificado para realizar mais processamento ou validação.
curl -X PUT 'http://127.0.0.1:9180/apisix/admin/routes/2' \
--header 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' \
--header 'Content-Type: application/json' \
--data-raw '
{
"uri": "/filter",
"plugins":{
"serverless-pre-function": {
"phase": "access",
"functions": [
"return function(conf, ctx)
local core = require(\"apisix.core\")
local cjson = require(\"cjson.safe\")
-- Get the request body
local body = core.request.get_body()
-- Decode the JSON body
local decoded_body = cjson.decode(body)
-- Hide the credit card number
decoded_body.credit_card_number = \"****-****-****-****\"
core.response.exit(200, decoded_body);
end"
]
}
}
}'
Passo 3: Testar a configuração
Agora é hora de testar a configuração geral. Com o comando curl abaixo, enviamos uma solicitação HTTP GET para o endpoint http://127.0.0.1:9080/my-credit-cards
.
curl http://127.0.0.1:9080/my-credit-cards
Temos a rota correspondente configurada no segundo passo para usar o plugin pipeline-request
com dois nós, esta solicitação acionará o pipeline para recuperar as informações do cartão de crédito do endpoint https://random-data-api.com/api/v2/credit_cards
, filtrar os dados sensíveis usando o endpoint http://127.0.0.1:9080/filter
e retornar a resposta modificada ao cliente. Veja a saída:
{
"uid":"a66239cd-960b-4e14-8d3c-a8940cedd907",
"credit_card_expiry_date":"2025-05-10",
"credit_card_type":"visa",
"credit_card_number":"****-****-****-****",
"id":2248
}
Como você pode ver, ele substitui o número do cartão de crédito no corpo da solicitação (na verdade, é a resposta da primeira chamada de API na cadeia) por asteriscos.
Resumo
Até agora, aprendemos que nosso plugin personalizado de pipeline request para o API Gateway Apache APISIX nos permite definir uma sequência de chamadas de API como um pipeline em uma ordem específica. Também podemos usar este novo plugin em combinação com os existentes para habilitar autenticação, segurança e outros recursos de API Gateway para nossos endpoints de API.