Integrações de proxy do Lambda no API Gateway - Amazon API Gateway

Integrações de proxy do Lambda no API Gateway

A seção a seguir mostra como usar uma integração de proxy do Lambda.

Compreender a integração de proxy do Lambda do API Gateway

A integração de proxy do Lambda do Amazon API Gateway é um mecanismo simples, potente e ágil para criar uma API com uma configuração de um único método de API. A integração de proxy do Lambda permite que o cliente chame uma única função do Lambda no backend. A função acessa muitos recursos ou recursos de outros serviços da AWS, incluindo chamadas para outras funções do Lambda.

Na integração de proxy do Lambda, quando um cliente envia uma solicitação de API, o API Gateway repassa um objeto do evento para a função do Lambda integrada, exceto pelo fato de que a ordem dos parâmetros da solicitação não é preservada. Esses dados de solicitação incluem cabeçalhos de solicitação, parâmetros de strings de consulta, variáveis de caminho URL, carga e dados de configuração da API. Os dados de configuração podem incluir o nome do estágio de implantação atual, variáveis de estágio, identidade do usuário ou contexto de autorização (se houver). A função do Lambda do backend analisa os dados da solicitação recebida para determinar a resposta que ela retorna. Para que o API Gateway passe a saída do Lambda como a resposta da API para o cliente, a função do Lambda deve retornar o resultado neste formato.

Como o API Gateway não interfere muito entre o cliente e a função do Lambda do backend para a integração de proxy do Lambda, o cliente e a função do Lambda integrada podem se adaptar às alterações mútuas sem quebrar a configuração de integração existente da API. Para permitir isso, o cliente deve seguir os protocolos de aplicação promulgados pela função do Lambda de backend.

É possível configurar uma integração de proxy do Lambda para qualquer método de API. Mas uma integração de proxy do Lambda é mais potente quando configurada para um método de API que envolve um recurso de proxy genérico. O recurso de proxy genérico pode ser identificado por um modelo variável de caminho especial de {proxy+}, pelo espaço reservado de método ANY ou ambos. O cliente pode passar a entrada da função do Lambda de backend na solicitação recebida como parâmetros da solicitação ou carga aplicável. Os parâmetros de solicitação incluem cabeçalhos, variáveis de caminho URL, parâmetros de string de consulta e a carga aplicável. A função do Lambda integrada verifica todas as fontes de entrada antes de processar a solicitação e responder ao cliente com mensagens de erro significativas se qualquer uma das entradas obrigatórias estiver ausente.

Ao chamar um método de API integrado ao método HTTP genérico de ANY e o recurso genérico de {proxy+}, o cliente envia uma solicitação com um método HTTP específico em vez de ANY. O cliente também especifica determinado caminho URL em vez de {proxy+}, e inclui todos os cabeçalhos necessários, parâmetros de strings de consulta ou uma carga aplicável.

A lista a seguir resume comportamentos de tempo de execução de diferentes métodos de API com a integração de proxy do Lambda:

  • ANY /{proxy+}: o cliente deve escolher determinado método HTTP, definir determinada hierarquia de caminho de recursos e pode definir todos os cabeçalhos, parâmetros de strings de consulta e carga aplicáveis para passar os dados como entrada para a função do Lambda integrada.

  • ANY /res: o cliente deve escolher determinado método HTTP e pode definir todos os cabeçalhos, parâmetros de strings de consulta e carga aplicáveis para passar os dados como entrada para a função do Lambda integrada.

  • GET|POST|PUT|... /{proxy+}: o cliente pode definir determinada hierarquia de caminho de recursos, cabeçalhos, parâmetros de strings de consulta e carga aplicáveis para passar os dados como entrada para a função do Lambda integrada.

  • GET|POST|PUT|... /res/{path}/...: o cliente deve escolher determinado segmento de caminho (para a variável {path}) e pode definir os cabeçalhos de solicitação, parâmetros de strings de consulta e carga aplicáveis para passar os dados de entrada para a função do Lambda integrada.

  • GET|POST|PUT|... /res: o cliente pode escolher os cabeçalhos de solicitação, parâmetros de strings de consulta e carga aplicáveis para passar dados de entrada para a função do Lambda integrada.

Tanto o recurso de proxy de {proxy+} quanto o recurso personalizado de {custom} são expressos como modelos de variáveis de caminho. No entanto, {proxy+} pode indicar qualquer recurso ao longo de uma hierarquia de caminho, enquanto {custom} refere-se apenas a determinado segmento de caminho. Por exemplo, um supermercado pode organizar seu inventário de produtos online por nomes de departamento, categorias de produtos e tipos de produtos. O site do supermercado pode representar os produtos disponíveis pelos seguintes modelos de variáveis de caminho de recursos personalizados: /{department}/{produce-category}/{product-type}. Por exemplo, maçãs são representadas por /produce/fruit/apple e cenouras por /produce/vegetables/carrot. Ele também pode usar /{proxy+} para representar qualquer departamento, categoria ou tipo de produto que o cliente pode procurar ao fazer compras na loja online. Por exemplo, /{proxy+} pode indicar qualquer um dos seguintes itens:

  • /produce

  • /produce/fruit

  • /produce/vegetables/carrot

Para permitir que os clientes procurem qualquer produto disponível, a categoria do produto e o departamento associado, você pode expor um único método de GET /{proxy+} com permissões somente leitura. Da mesma forma, para permitir que um supervisor atualize o inventário do departamento do produce, você pode configurar outro método único de PUT /produce/{proxy+} com as permissões de leitura/gravação. Para permitir que um caixa atualize o total de um vegetal, você pode configurar um método POST /produce/vegetables/{proxy+} com permissões de leitura/gravação. Para permitir que um gerente de loja realize qualquer ação possível em qualquer produto disponível, o desenvolvedor da loja online pode expor o método ANY /{proxy+} com permissões de leitura/gravação. Em qualquer caso, na ocasião da execução, o cliente ou o funcionário deve selecionar um produto específico de determinado tipo em um departamento escolhido, uma categoria de produto específica em um departamento escolhido ou um departamento específico.

Para obter mais informações sobre como configurar integrações de proxy do API Gateway, consulte Configurar a integração de proxy com um recurso de proxy.

A integração de proxy exige que o cliente tenha um conhecimento mais detalhado dos requisitos de backend. Portanto, para garantir uma melhor performance das aplicações e da experiência do usuário, o desenvolvedor de backend deve comunicar claramente ao desenvolvedor cliente os requisitos do backend e fornecer um mecanismo de feedback de erro robusto quando os requisitos não são atendidos.

Suporte para cabeçalhos de vários valores e parâmetros de string de consulta

Agora o API Gateway oferece suporte a vários cabeçalhos e parâmetros de string de consulta que possuem o mesmo nome. Cabeçalhos de vários valores, bem como cabeçalhos e parâmetros de valor único, podem ser combinados nas mesmas solicitações e respostas. Para ter mais informações, consulte Formato de entrada de uma função do Lambda para integração de proxy e Formato de saída de uma função do Lambda para integração de proxy.

Formato de entrada de uma função do Lambda para integração de proxy

Com a integração de proxy do Lambda, o API Gateway mapeia toda a solicitação do cliente para o parâmetro event de entrada da função do Lambda de back-end. O exemplo a seguir mostra a estrutura de um evento que o API Gateway envia para uma integração de proxy do Lambda.

{ "resource": "/my/path", "path": "/my/path", "httpMethod": "GET", "headers": { "header1": "value1", "header2": "value1,value2" }, "multiValueHeaders": { "header1": [ "value1" ], "header2": [ "value1", "value2" ] }, "queryStringParameters": { "parameter1": "value1,value2", "parameter2": "value" }, "multiValueQueryStringParameters": { "parameter1": [ "value1", "value2" ], "parameter2": [ "value" ] }, "requestContext": { "accountId": "123456789012", "apiId": "id", "authorizer": { "claims": null, "scopes": null }, "domainName": "id.execute-api.us-east-1.amazonaws.com", "domainPrefix": "id", "extendedRequestId": "request-id", "httpMethod": "GET", "identity": { "accessKey": null, "accountId": null, "caller": null, "cognitoAuthenticationProvider": null, "cognitoAuthenticationType": null, "cognitoIdentityId": null, "cognitoIdentityPoolId": null, "principalOrgId": null, "sourceIp": "IP", "user": null, "userAgent": "user-agent", "userArn": null, "clientCert": { "clientCertPem": "CERT_CONTENT", "subjectDN": "www.example.com", "issuerDN": "Example issuer", "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1", "validity": { "notBefore": "May 28 12:30:02 2019 GMT", "notAfter": "Aug 5 09:36:04 2021 GMT" } } }, "path": "/my/path", "protocol": "HTTP/1.1", "requestId": "id=", "requestTime": "04/Mar/2020:19:15:17 +0000", "requestTimeEpoch": 1583349317135, "resourceId": null, "resourcePath": "/my/path", "stage": "$default" }, "pathParameters": null, "stageVariables": null, "body": "Hello from Lambda!", "isBase64Encoded": false }
nota

Na entrada:

  • A chave headers só pode conter cabeçalhos de valor único.

  • A chave multiValueHeaders pode conter cabeçalhos de vários valores e cabeçalhos de valor único.

  • Se você especificar valores para headers e multiValueHeaders, o API Gateway os mesclará em uma única lista. Se o mesmo de chave/valor for especificado em ambos, somente os valores de multiValueHeaders aparecerão na lista mesclada.

Na entrada para a função do Lambda do back-end, o objeto requestContext é um mapa de pares de chave/valor. Em cada par, a chave é o nome de uma propriedade de variável $context, e o valor é o valor dessa propriedade. O API Gateway pode adicionar novas chaves ao mapa.

Dependendo dos recursos que estão habilitados, o mapa requestContext pode variar de acordo com a API. Por exemplo, no exemplo anterior, nenhum tipo de autorização é especificado. Portanto, nenhuma propriedade $context.authorizer.* ou $context.identity.* está presente. Quando um tipo de autorização é especificado, isso faz com que o API Gateway repasse informações do usuário autorizado para o endpoint de integração em um objeto requestContext.identity da seguinte forma:

  • Quando o tipo de autorização é AWS_IAM, as informações do usuário autorizado incluem propriedades $context.identity.*.

  • Quando o tipo de autorização é COGNITO_USER_POOLS (autorizador do Amazon Cognito), as informações do usuário autorizado incluem propriedades $context.identity.cognito* e $context.authorizer.claims.*.

  • Quando o tipo de autorização é CUSTOM (autorizador do Lambda), as informações do usuário autorizado incluem propriedades $context.authorizer.principalId e outras $context.authorizer.* aplicáveis.

Formato de saída de uma função do Lambda para integração de proxy

Na integração de proxy do Lambda, o API Gateway requer a função do Lambda do backend para retornar a saída de acordo com o seguinte formato JSON:

{ "isBase64Encoded": true|false, "statusCode": httpStatusCode, "headers": { "headerName": "headerValue", ... }, "multiValueHeaders": { "headerName": ["headerValue", "headerValue2", ...], ... }, "body": "..." }

Na saída:

  • As chaves headers e multiValueHeaders podem ser não especificadas se nenhum cabeçalho de resposta extra precisar ser retornado.

  • A chave headers só pode conter cabeçalhos de valor único.

  • A chave multiValueHeaders pode conter cabeçalhos de vários valores e cabeçalhos de valor único. Você pode usar a chave multiValueHeaders para especificar todos os seus cabeçalhos extras, incluindo os de valor único.

  • Se você especificar valores para headers e multiValueHeaders, o API Gateway os mesclará em uma única lista. Se o mesmo de chave/valor for especificado em ambos, somente os valores de multiValueHeaders aparecerão na lista mesclada.

Para ativar o CORS da integração de proxy do Lambda, você deve adicionar Access-Control-Allow-Origin:domain-name à saída headers. domain-name pode ser * para qualquer nome de domínio. A saída body é organizado para o front-end como a carga de resposta do método. Se body for um blob binário, você poderá codificá-lo como uma string codificada em Base64, definindo isBase64Encoded como true e configurando */* como Binary Media Type (Tipo de mídia binário). Caso contrário, será possível defini-lo como false ou deixá-lo sem especificação.

nota

Para obter mais informações sobre como habilitar o suporte a binários, consulte Ativação do suporte binário usando o console do API Gateway. Para obter um exemplo de função do Lambda, consulte Exibir mídia binária de uma integração de proxy do Lambda no API Gateway.

Se a saída da função for de um formato diferente, o API Gateway retorna uma resposta de erro 502 Bad Gateway.

Para retornar uma resposta em uma função do Lambda em Node.js, você poderá usar comandos como o seguinte:

  • Para retornar um resultado bem-sucedido, chame callback(null, {"statusCode": 200, "body": "results"}).

  • Para lançar uma exceção, chame callback(new Error('internal server error')).

  • Para um erro no lado do cliente, (se, por exemplo, um parâmetro necessário estiver ausente), você poderá chamar callback(null, {"statusCode": 400, "body": "Missing parameters of ..."}) para retornar o erro sem lançar uma exceção.

Em uma função do Lambda async no Node.js, a sintaxe equivalente seria:

  • Para retornar um resultado bem-sucedido, chame return {"statusCode": 200, "body": "results"}.

  • Para lançar uma exceção, chame throw new Error("internal server error").

  • Para um erro no lado do cliente, (se, por exemplo, um parâmetro necessário estiver ausente), você poderá chamar return {"statusCode": 400, "body": "Missing parameters of ..."} para retornar o erro sem lançar uma exceção.