Tutorial: Criar uma API REST do API Gateway com integração sem proxy do Lambda - Amazon API Gateway

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Tutorial: Criar uma API REST do API Gateway com integração sem proxy do Lambda

Nesta demonstração, usamos o console do API Gateway para criar uma API que permite a um cliente chamar funções do Lambda por meio da integração não proxy do Lambda (também conhecida como integração personalizada). Para obter mais informações sobre AWS Lambda e as funções do Lambda, consulte o Guia do desenvolvedor do AWS Lambda.

Para facilitar o aprendizado, escolhemos uma função do Lambda simples com configuração mínima da API para orientar você pelas etapas de criação de uma API do API Gateway com a integração personalizada do Lambda. Quando necessário, descrevemos parte da lógica. Para ver um exemplo mais detalhado da integração personalizada do Lambda, consulte Tutorial: Crie uma API Calc REST com duas integrações AWS de serviços e uma integração Lambda sem proxy.

Antes de criar a API, configure o backend do Lambda criando uma função do Lambda no AWS Lambda, conforme descrito a seguir.

Criar uma função do Lambda para integração não proxy do Lambda

nota

A criação de funções do Lambda pode resultar em cobranças em sua AWS conta.

Nesta etapa, crie uma função do Lambda no estilo “Hello, World!” para a integração personalizada do Lambda. Durante esta demonstração, a função é chamada GetStartedLambdaIntegration.

A implementação dessa função do Lambda GetStartedLambdaIntegration é a seguinte:

Node.js
'use strict'; var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; var times = ['morning', 'afternoon', 'evening', 'night', 'day']; console.log('Loading function'); export const handler = function(event, context, callback) { // Parse the input for the name, city, time and day property values let name = event.name === undefined ? 'you' : event.name; let city = event.city === undefined ? 'World' : event.city; let time = times.indexOf(event.time)<0 ? 'day' : event.time; let day = days.indexOf(event.day)<0 ? null : event.day; // Generate a greeting let greeting = 'Good ' + time + ', ' + name + ' of ' + city + '. '; if (day) greeting += 'Happy ' + day + '!'; // Log the greeting to CloudWatch console.log('Hello: ', greeting); // Return a greeting to the caller callback(null, { "greeting": greeting }); };
Python
import json days = { 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'} times = {'morning', 'afternoon', 'evening', 'night', 'day'} def lambda_handler(event, context): print(event) # parse the input for the name, city, time, and day property values try: if event['name']: name = event['name'] except KeyError: name = 'you' try: if event['city']: city = event['city'] except KeyError: city = 'World' try: if event['time'] in times: time = event['time'] else: time = 'day' except KeyError: time = 'day' try: if event['day'] in days: day = event['day'] else: day = '' except KeyError: day = '' # Generate a greeting greeting = 'Good ' + time + ', ' + name + ' of ' + \ city + '.' + ['', ' Happy ' + day + '!'][day != ''] # Log the greeting to CloudWatch print(greeting) # Return a greeting to the caller return {"greeting": greeting}

Para a integração personalizada do Lambda o API Gateway transmite a entrada para a função do Lambda do cliente como o corpo da solicitação de integração. O objeto event do manipulador da função do Lambda é a entrada.

Nossa função do Lambda é simples. Ela analisa o objeto de entrada event para as propriedades name, city, timee day. Em seguida, ela retorna uma saudação, como um objeto JSON de {"message":greeting}, para o autor da chamada. A mensagem é no padrão "Good [morning|afternoon|day], [name|you] in [city|World]. Happy day!". Presume-se que a entrada para a função do Lambda seja um dos seguintes objetos JSON:

{ "city": "...", "time": "...", "day": "...", "name" : "..." }

Para obter mais informações, consulte o Guia do desenvolvedor do AWS Lambda.

Além disso, a função registra sua execução na Amazon CloudWatch chamandoconsole.log(...). Isso é útil para rastrear as chamadas ao depurar a função. Para permitir que a GetStartedLambdaIntegration função registre a chamada, defina uma função do IAM com políticas apropriadas para a função Lambda para criar os CloudWatch fluxos e adicionar entradas de registro aos fluxos. O console do Lambda orienta você na criação das funções e políticas do IAM necessárias.

Se você configurar a API sem usar o console do API Gateway, tal como ao importar uma API de um arquivo do OpenAPI, é necessário criar explicitamente, se necessário, e configurar uma função e política de invocação para que o API Gateway invoque as funções do Lambda. Para obter mais informações sobre como configurar funções de invocação e execução do Lambda para uma API do API Gateway, consulte Controlar o acesso a uma API com permissões do IAM.

Em comparação com GetStartedLambdaProxyIntegration, a função do Lambda para a integração de proxy do Lambda, a função GetStartedLambdaIntegration do Lambda para a integração personalizada do Lambda recebe apenas a entrada do corpo da solicitação de integração da API do API Gateway. A função pode retornar uma saída de qualquer objeto JSON, uma string, um número, um Booleano ou até mesmo um blob binário. Em contrapartida, a função do Lambda para a integração de proxy do Lambda pode aceitar a entrada de quaisquer dados da solicitação, mas deve retornar uma saída de determinado objeto JSON. A função GetStartedLambdaIntegration para a integração personalizada do Lambda pode ter os parâmetros de solicitação de API como entrada, desde que o API Gateway mapeie os parâmetros de solicitação de API necessários para o corpo da solicitação de integração antes de encaminhar a solicitação do cliente ao backend. Para que isso aconteça, o desenvolvedor da API deve criar um modelo de mapeamento e configurá-lo no método de API ao criar a API.

Agora, crie a função do Lambda GetStartedLambdaIntegration.

Como criar a função do Lambda GetStartedLambdaIntegration para integração personalizada do Lambda
  1. Abra o AWS Lambda console em https://console.aws.amazon.com/lambda/.

  2. Execute um destes procedimentos:

    • Se a página de boas-vindas for exibida, escolha Get Started Now (Começar a usar agora) e Create function (Criar função).

    • Se a página da lista Lambda > Functions (Lambda > Funções) for exibida, escolha Create function (Criar função).

  3. Escolha Author from scratch (Criar do zero).

  4. Na tela Author from scratch (Criar do zero), faça o seguinte:

    1. Em Name (Nome), insira GetStartedLambdaIntegration como o nome da função do Lambda.

    2. Em Tempo de execução, escolha o último runtime Node.js ou Python compatível.

    3. Em Permissions (Permissões), expanda Change default execution role (Alterar função de execução padrão). Na lista suspensa Perfil de execução, escolha Criar perfil com base em modelos de política da AWS .

    4. Para Role name (Nome da função), insira um nome para sua função (por exemplo, GetStartedLambdaIntegrationRole).

    5. Para Policy templates (Modelos de política), escolha Simple microservice permissions (Permissões de microsserviço simples).

    6. Escolha Create function (Criar função).

  5. No painel Configure function (Configurar função), em Function code (Código de função) faça o seguinte:

    1. Copie o código da função do Lambda listado no início desta seção e cole-o no editor de código em linha.

    2. Deixe as opções padrão para todos os outros campos nesta seção.

    3. Escolha Deploy (Implantar).

  6. Para testar a função recém-criada, escolha a guia Teste.

    1. Em Nome do evento, insira HelloWorldTest.

    2. Para JSON do evento, substitua o código padrão pelo seguinte.

      { "name": "Jonny", "city": "Seattle", "time": "morning", "day": "Wednesday" }
    3. Escolha Test (Testar) para invocar a função. A seção Execution result: succeeded (Resultada da execução: bem-sucedida) é exibida. Expanda Detalhes veja a saída a seguir.

      { "greeting": "Good morning, Jonny of Seattle. Happy Wednesday!" }

      A saída também é gravada em CloudWatch Logs.

Como exercício extra, você pode usar o console do IAM para visualizar a função do IAM (GetStartedLambdaIntegrationRole) criada como parte da criação da função do Lambda. Há duas políticas em linha anexadas à esta função do IAM. Uma estipula as permissões mais básicas para execução do Lambda. Ele permite chamar o CloudWatch CreateLogGroup para qualquer CloudWatch recurso da sua conta na região em que a função Lambda foi criada. Essa política também permite criar CloudWatch fluxos e registrar eventos para a função HelloWorldForLambdaIntegration Lambda.

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "logs:CreateLogGroup", "Resource": "arn:aws:logs:region:account-id:*" }, { "Effect": "Allow", "Action": [ "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": [ "arn:aws:logs:region:account-id:log-group:/aws/lambda/GetStartedLambdaIntegration:*" ] } ] }

O outro documento de política se aplica à invocação AWS de outro serviço que não é usado neste exemplo. Você pode ignorá-lo por enquanto.

Associada à função do IAM, há uma entidade confiável, que é lambda.amazonaws.com. Esta é a relação de confiança:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }

A combinação dessa relação de confiança e da política em linha possibilita que a função Lambda invoque console.log() uma função para registrar eventos no Logs. CloudWatch

Se você não usou o AWS Management Console para criar a função Lambda, você precisa seguir esses exemplos para criar a função e as políticas do IAM necessárias e, em seguida, anexar manualmente a função à sua função.

Criar uma API com integração não proxy do Lambda

Com a função do Lambda (GetStartedLambdaIntegration) criada e testada, você está pronto para expor a função por meio de uma API do API Gateway. Para fins de ilustração, a função do Lambda está exposta com um método HTTP genérico. Usamos o corpo de solicitação, uma variável do caminho URL, uma string de consulta e um cabeçalho para receber os dados de entrada necessários do cliente. Ativamos o validador de solicitações do API Gateway para a API a fim de garantir que todos os dados necessários sejam definidos e especificados apropriadamente. Configuramos um modelo para mapeamento para o API Gateway para transformar os dados de solicitação fornecidos pelo cliente no formato válido, conforme exigido pela função de backend do Lambda.

Como criar uma API com uma integração não proxy do Lambda
  1. Inicie uma sessão no console do API Gateway em https://console.aws.amazon.com/apigateway.

  2. Se esta for a primeira vez que você usa o API Gateway, você verá uma página com os recursos do serviço. Em REST API, escolha Build (Criar). Quando o pop-up Create Example API (Criar API de exemplo) for exibido, escolha OK.

    Se essa não for a primeira vez que você usa o API Gateway, escolha Create API (Criar API). Em REST API, escolha Build (Criar).

  3. Em API name (Nome da API), insira LambdaNonProxyAPI.

  4. (Opcional) Em Description (Descrição), insira uma descrição.

  5. Mantenha Tipo de endpoint da API definido como Regional.

  6. Selecione Criar API.

Depois de criar uma API, você criará um recurso /{city}. Este é um exemplo de recurso com uma variável de caminho que recebe uma entrada do cliente. Posteriormente, você vai associar essa variável de caminho à entrada da função do Lambda usando um modelo de mapeamento.

Para criar um recurso
  1. Selecione Criar recurso.

  2. Mantenha Recurso proxy desativado.

  3. Mantenha Caminho do recurso como /.

  4. Em Resource Name (Nome do recurso), insira {city}.

  5. Mantenha CORS (Compartilhamento de recursos de origem cruzada) desativado.

  6. Selecione Criar recurso.

Depois de criar um recurso /{city}, você criará um método ANY. O verbo HTTP ANY é um espaço reservado para um método HTTP válido que um cliente envia na ocasião da execução. Este exemplo mostra que o método ANY pode ser usado para integração personalizada do Lambda assim como para integração de proxy do Lambda.

Como criar um método ANY
  1. Selecione o recurso /{city} e, depois, Criar método.

  2. Em Tipo de método, selecione ANY.

  3. Em Tipo de integração, selecione Função do Lambda.

  4. Mantenha a opção Integração do proxy do Lambda desativada.

  5. Para a função Lambda, selecione Região da AWS onde você criou sua função Lambda e, em seguida, insira o nome da função.

  6. Para usar o valor de tempo limite padrão de 29 segundos, deixe a opção Tempo limite padrão ativada. Para definir um tempo limite personalizado, selecione Tempo limite padrão e insira um valor de tempo limite entre 50 e 29000 milissegundos.

  7. Escolha Criar método.

Depois de criar o método ANY, você vai ativar um validador de solicitações para uma variável de caminho de URL, uma string de consulta e um cabeçalho a fim de garantir que todos os dados necessários sejam definidos e especificados corretamente. Neste exemplo, você vai criar um parâmetro de string de consulta time e um cabeçalho day.

Como ativar um validador de solicitações
  1. Na guia Solicitação de método, em Configurações de solicitação de método, escolha Editar.

  2. Em Validador de solicitação, selecione Validar parâmetros de string de consulta e cabeçalhos.

  3. Selecione Parâmetros de string de consulta de URL e faça o seguinte:

    1. Escolha Add query string (Adicionar string de consulta).

    2. Em Nome, digite time.

    3. Ative a opção Obrigatório.

    4. Mantenha Armazenamento em cache desativado.

  4. Selecione Cabeçalhos de solicitação HTTP e faça o seguinte:

    1. Escolha Add header (Adicionar cabeçalho).

    2. Em Nome, digite day.

    3. Ative a opção Obrigatório.

    4. Mantenha Armazenamento em cache desativado.

  5. Escolha Salvar.

Depois de ativar um validador de solicitações, você vai configurar a solicitação de integração do método ANY adicionando um modelo de mapeamento de corpo para transformar a solicitação recebida em uma carga útil do JSON, conforme exigido pela função do Lambda de back-end.

Como configurar a solicitação de integração
  1. Na guia Solicitação de integração, nas configurações da solicitação de integração, escolha Editar.

  2. Em Passagem do corpo da solicitação, selecione Quando não há modelos definidos (recomendado).

  3. Selecione Modelos de mapeamento.

  4. Escolha Add mapping template (Adicionar modelo de mapeamento).

  5. Em Tipo de conteúdo, insira application/json.

  6. Em Corpo do modelo, insira o seguinte código:

    #set($inputRoot = $input.path('$')) { "city": "$input.params('city')", "time": "$input.params('time')", "day": "$input.params('day')", "name": "$inputRoot.callerName" }
  7. Escolha Save (Salvar).

Testar a chamada do método de API

O console do API Gateway fornece uma instalação de testes para que você teste a invocação à API antes que ela seja implantada. Você pode usar o recurso de teste do console para testar a API enviando a seguinte solicitação:

POST /Seattle?time=morning day:Wednesday { "callerName": "John" }

Nesta solicitação de teste, você definirá ANY como POST, definirá {city} como Seattle, atribuirá Wednesday como o valor de cabeçalho day e atribuirá "John" como o valor callerName.

Como testar o método ANY
  1. Selecione a guia Testar. Talvez seja necessário selecionar o botão de seta para a direita para mostrar a guia.

  2. Em Tipo de método, selecione POST.

  3. Em Caminho, em cidade, insira Seattle.

  4. Em Strings de consulta, digite time=morning.

  5. Em Cabeçalhos, insira day:Wednesday.

  6. Em Corpo da solicitação, insira { "callerName": "John" }.

  7. Escolha Test (Testar).

Verifique se a carga de resposta retornada é como se segue:

{ "greeting": "Good morning, John of Seattle. Happy Wednesday!" }

Também é possível visualizar os logs para examinar como o API Gateway processa a solicitação e a resposta.

Execution log for request test-request Thu Aug 31 01:07:25 UTC 2017 : Starting execution for request: test-invoke-request Thu Aug 31 01:07:25 UTC 2017 : HTTP Method: POST, Resource Path: /Seattle Thu Aug 31 01:07:25 UTC 2017 : Method request path: {city=Seattle} Thu Aug 31 01:07:25 UTC 2017 : Method request query string: {time=morning} Thu Aug 31 01:07:25 UTC 2017 : Method request headers: {day=Wednesday} Thu Aug 31 01:07:25 UTC 2017 : Method request body before transformations: { "callerName": "John" } Thu Aug 31 01:07:25 UTC 2017 : Request validation succeeded for content type application/json Thu Aug 31 01:07:25 UTC 2017 : Endpoint request URI: https://lambda.us-west-2.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:GetStartedLambdaIntegration/invocations Thu Aug 31 01:07:25 UTC 2017 : Endpoint request headers: {x-amzn-lambda-integration-tag=test-request, Authorization=****************************************************************************************************************************************************************************************************************************************************************************************************************************************338c72, X-Amz-Date=20170831T010725Z, x-amzn-apigateway-api-id=beags1mnid, X-Amz-Source-Arn=arn:aws:execute-api:us-west-2:123456789012:beags1mnid/null/POST/{city}, Accept=application/json, User-Agent=AmazonAPIGateway_beags1mnid, X-Amz-Security-Token=FQoDYXdzELL//////////wEaDMHGzEdEOT/VvGhabiK3AzgKrJw+3zLqJZG4PhOq12K6W21+QotY2rrZyOzqhLoiuRg3CAYNQ2eqgL5D54+63ey9bIdtwHGoyBdq8ecWxJK/YUnT2Rau0L9HCG5p7FC05h3IvwlFfvcidQNXeYvsKJTLXI05/yEnY3ttIAnpNYLOezD9Es8rBfyruHfJfOqextKlsC8DymCcqlGkig8qLKcZ0hWJWVwiPJiFgL7laabXs++ZhCa4hdZo4iqlG729DE4gaV1mJVdoAagIUwLMo+y4NxFDu0r7I0/EO5nYcCrppGVVBYiGk7H4T6sXuhTkbNNqVmXtV3ch5bOlh7 [TRUNCATED] Thu Aug 31 01:07:25 UTC 2017 : Endpoint request body after transformations: { "city": "Seattle", "time": "morning", "day": "Wednesday", "name" : "John" } Thu Aug 31 01:07:25 UTC 2017 : Sending request to https://lambda.us-west-2.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:GetStartedLambdaIntegration/invocations Thu Aug 31 01:07:25 UTC 2017 : Received response. Integration latency: 328 ms Thu Aug 31 01:07:25 UTC 2017 : Endpoint response body before transformations: {"greeting":"Good morning, John of Seattle. Happy Wednesday!"} Thu Aug 31 01:07:25 UTC 2017 : Endpoint response headers: {x-amzn-Remapped-Content-Length=0, x-amzn-RequestId=c0475a28-8de8-11e7-8d3f-4183da788f0f, Connection=keep-alive, Content-Length=62, Date=Thu, 31 Aug 2017 01:07:25 GMT, X-Amzn-Trace-Id=root=1-59a7614d-373151b01b0713127e646635;sampled=0, Content-Type=application/json} Thu Aug 31 01:07:25 UTC 2017 : Method response body after transformations: {"greeting":"Good morning, John of Seattle. Happy Wednesday!"} Thu Aug 31 01:07:25 UTC 2017 : Method response headers: {X-Amzn-Trace-Id=sampled=0;root=1-59a7614d-373151b01b0713127e646635, Content-Type=application/json} Thu Aug 31 01:07:25 UTC 2017 : Successfully completed execution Thu Aug 31 01:07:25 UTC 2017 : Method completed with status: 200

Os logs mostram a solicitação recebida antes do mapeamento e a solicitação de integração após o mapeamento. Quando um teste falha, os logs são úteis para avaliar se a entrada original está correta ou se o modelo de mapeamento funciona corretamente.

Implantar a API

A invocação de teste é uma simulação e tem limitações. Por exemplo, ela ignora qualquer mecanismo de autorização promulgado na API. Para testar a execução da API em tempo real, você deve implantar a API primeiro. Para implantar uma API, você cria um estágio para criar um snapshot da API naquele momento. O nome do estágio também define o caminho base após o nome de host padrão da API. O recurso raiz da API é anexado após o nome do estágio. Quando você modifica a API, deve reimplantá-la em um estágio novo ou existente antes que as alterações entrem em vigor.

Para implantar a API em um estágio
  1. Escolha Deploy API (Implantar API).

  2. Em Estágio, selecione Novo estágio.

  3. Em Stage name (Nome do estágio), insira test.

    nota

    A entrada deve ser texto codificado UTF-8 (ou seja, não localizado).

  4. (Opcional) Em Description (Descrição), insira uma descrição.

  5. Escolha Implantar.

Em Detalhes do estágio, escolha o ícone de cópia para copiar o URL de invocação da API. O padrão geral do URL básico da API é https://api-id.region.amazonaws.com/stageName. Por exemplo, o URL básico da API (beags1mnid) criada na região us-west-2 e implantada no estágio test é https://beags1mnid.execute-api.us-west-2.amazonaws.com/test.

Testar a API em uma etapa de implantação

Há várias maneiras para testar uma API implantada. Para solicitações GET usando apenas variáveis de caminho do URL ou parâmetros de strings de consulta, é possível digitar o URL de recurso da API em um navegador. Para outros métodos, é necessário usar utilitários de teste de API REST mais avançados, como o POSTMAN ou o cURL.

Para testar a API usando cURL
  1. Abra uma janela de terminal em seu computador local conectado à Internet.

  2. Para testar POST /Seattle?time=evening:

    Copie o seguinte comando cURL e cole-o na janela do terminal.

    curl -v -X POST \ 'https://beags1mnid.execute-api.us-west-2.amazonaws.com/test/Seattle?time=evening' \ -H 'content-type: application/json' \ -H 'day: Thursday' \ -H 'x-amz-docs-region: us-west-2' \ -d '{ "callerName": "John" }'

    Você receberá uma resposta bem-sucedida com a seguinte carga:

    {"greeting":"Good evening, John of Seattle. Happy Thursday!"}

    Se você alterar POST para PUT nesta solicitação de método, obterá a mesma resposta.

Limpar

Se você não precisar mais das funções do Lambda criadas para esta demonstração, poderá excluí-las agora. Você também pode excluir os recursos do IAM que o acompanham.

Atenção

Se você pretende completar as outras demonstrações desta série, não exclua a função de execução Lambda ou a função de invocação do Lambda. Se você excluir uma função do Lambda da qual as suas APIs dependem, essas APIs deixarão de funcionar. A exclusão de uma função do Lambda não pode ser desfeita. Se quiser usar a função do Lambda novamente, você deverá recriar essa função.

Se você excluir um recurso do IAM do qual depende uma função do Lambda, esta última deixará de funcionar, juntamente com as APIs que dependem dessa função. A exclusão de um recurso do IAM não pode ser desfeita. Se quiser usar o recurso do IAM novamente, você deverá recriá-lo.

Como excluir as funções do Lambda
  1. Faça login no AWS Management Console e abra o AWS Lambda console em https://console.aws.amazon.com/lambda/.

  2. Na lista de funções, escolha GetHelloWorld, selecione Actions (Ações) e, em seguida, Delete function (Excluir função). Quando solicitado, escolha Delete (Excluir) novamente.

  3. Na lista de funções, escolha GetHelloWithName, selecione Actions (Ações) e, em seguida, Delete function (Excluir função). Quando solicitado, escolha Delete (Excluir) novamente.

Como excluir os recursos do IAM associados
  1. Abra o console do IAM em https://console.aws.amazon.com/iam/.

  2. Em Details (Detalhes), escolha Roles (Funções).

  3. Na lista de funções, escolha API GatewayLambdaExecRole, escolha Ações de função e, em seguida, escolha Excluir função. Quando solicitado, escolha Yes, Delete (Sim, excluir).

  4. Em Details (Detalhes), escolha Policies (Políticas).

  5. Na lista de políticas, escolha API GatewayLambdaExecPolicy, escolha Ações de política e, em seguida, escolha Excluir. Quando solicitado, escolha Delete (Excluir).