AWS Lambda
Guia do desenvolvedor

Tutorial: usar o AWS Lambda com o Amazon API Gateway

Neste exemplo, você cria uma API simples usando o Amazon API Gateway. Um Amazon API Gateway é um conjunto de recursos e métodos. Para este tutorial, você cria um recurso (DynamoDBManager) e define um método (POST) nele. O método é respaldado por uma função do Lambda (LambdaFunctionOverHttps). Ou seja, quando você chama a API por meio de um endpoint HTTPS, o Amazon API Gateway invoca a função do Lambda.

O método POST no recurso DynamoDBManager oferece suporte para as seguintes operações do DynamoDB:

  • Criar, atualizar e excluir um item.

  • Ler um item.

  • Examinar um item.

  • Outras operações (eco, ping), não relacionadas ao DynamoDB, que você pode usar para testes.

A carga da solicitação que você envia na solicitação POST identifica a operação do DynamoDB e fornece os dados necessários. Por exemplo:

  • Veja a seguir um exemplo de carga de solicitação para uma operação de criação de item do DynamoDB:

    { "operation": "create", "tableName": "lambda-apigateway", "payload": { "Item": { "id": "1", "name": "Bob" } } }
  • Veja a seguir um exemplo de carga de solicitação para uma operação de leitura de item do DynamoDB:

    { "operation": "read", "tableName": "lambda-apigateway", "payload": { "Key": { "id": "1" } } }
  • Veja a seguir um exemplo de carga de solicitação para uma operação echo. Em seguida, uma solicitação HTTP POST é enviada ao endpoint, usando os seguintes dados no corpo de solicitação.

    { "operation": "echo", "payload": { "somekey1": "somevalue1", "somekey2": "somevalue2" } }

nota

O API Gateway oferece recursos avançados, tais como:

  • Transmissão de toda a solicitação – Uma função do Lambda pode receber toda a solicitação HTTP (em vez de apenas o corpo da solicitação) e definir a resposta HTTP (em vez de apenas o corpo da resposta) usando o tipo de integração AWS_PROXY.

  • Métodos genéricos – Mapeiam todos os métodos de um recurso de API para uma única função do Lambda com um único mapeamento, usando o método genérico ANY.

  • Recursos genéricos – Mapeia todos os subcaminhos de um recurso para uma função do Lambda sem qualquer configuração adicional usando o novo parâmetro de caminho ({proxy+}).

Para saber mais sobre esses recursos do API Gateway, consulte Configurar integração de proxy para um recurso de proxy.

Pré-requisitos

Este tutorial pressupõe que você tenha algum conhecimento das operações básicas do Lambda e do console do Lambda. Caso ainda não tenha feito isso, siga as instruções em Conceitos básicos do AWS Lambda para criar sua primeira função do Lambda.

Para seguir os procedimentos neste manual, você precisa de um terminal de linha de comando ou de um shell para executar os comandos. Nas listagens, os comandos são mostrados precedidos por um símbolo de prompt ($) e pelo nome do diretório atual, quando apropriado:

~/lambda-project$ this is a command this is output

Para comandos longos, um caractere de escape (\) é usado para dividir um comando em várias linhas.

No Linux e no macOS, use seu gerenciador preferido de pacotes e de shell. No Windows 10, você pode instalar o Subsistema Windows para Linux para obter uma versão do Ubuntu integrada com o Windows e o Bash.

Criar a função de execução

Crie a função de execução que dá à sua função permissão para acessar recursos do AWS.

Para criar uma função de execução

  1. Abra a página Roles no console do IAM.

  2. Selecione Create role.

  3. Crie uma função com as seguintes propriedades.

    • Entidade confiável – Lambda.

    • Nome da funçãolambda-apigateway-role.

    • Permissions (Permissões) – Política personalizada com permissão para DynamoDB e CloudWatch Logs.

      { "Version": "2012-10-17", "Statement": [ { "Sid": "Stmt1428341300017", "Action": [ "dynamodb:DeleteItem", "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:Query", "dynamodb:Scan", "dynamodb:UpdateItem" ], "Effect": "Allow", "Resource": "*" }, { "Sid": "", "Resource": "*", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Effect": "Allow" } ] }

A política personalizada tem as permissões de que a função precisa para gravar dados no DynamoDB e fazer upload de logs. Observe o nome de recurso da Amazon (ARN) da função para uso posterior.

Criar a função

O exemplo de código a seguir recebe uma entrada de evento do API Gateway e processa as mensagens que ela contém. Na ilustração, o código grava alguns dos dados de eventos de entrada no CloudWatch Logs.

nota

Para o código de amostra em outras linguagens, consulte Código da função de amostra.

exemplo index.js

console.log('Loading function'); var AWS = require('aws-sdk'); var dynamo = new AWS.DynamoDB.DocumentClient(); /** * Provide an event that contains the following keys: * * - operation: one of the operations in the switch statement below * - tableName: required for operations that interact with DynamoDB * - payload: a parameter to pass to the operation being performed */ exports.handler = function(event, context, callback) { //console.log('Received event:', JSON.stringify(event, null, 2)); var operation = event.operation; if (event.tableName) { event.payload.TableName = event.tableName; } switch (operation) { case 'create': dynamo.put(event.payload, callback); break; case 'read': dynamo.get(event.payload, callback); break; case 'update': dynamo.update(event.payload, callback); break; case 'delete': dynamo.delete(event.payload, callback); break; case 'list': dynamo.scan(event.payload, callback); break; case 'echo': callback(null, "Success"); break; case 'ping': callback(null, "pong"); break; default: callback('Unknown operation: ${operation}'); } };

Para criar a função

  1. Copie o código de amostra em um arquivo chamado index.js.

  2. Crie um pacote de implantação.

    $ zip function.zip index.js
  3. Crie uma função do Lambda com o comando create-function.

    $ aws lambda create-function --function-name LambdaFunctionOverHttps \ --zip-file fileb://function.zip --handler index.handler --runtime nodejs8.10 \ --role arn:aws:iam::123456789012:role/service-role/lambda-apigateway-role

Testar a função do Lambda

Invoque a função manualmente usando os dados de evento de exemplo. Recomendamos que você invoque a função usando o console, pois ele fornece uma interface de usuário amigável para revisar os resultados da execução, incluindo o resumo da execução, os logs gravados pelo código e os resultados retornados pela função—o console sempre realiza uma execução síncrona invocando a função do Lambda com o tipo de invocação RequestResponse).

Para testar a função do Lambda

  1. Copie o JSON a seguir em um arquivo e salve-o como input.txt.

    { "operation": "echo", "payload": { "somekey1": "somevalue1", "somekey2": "somevalue2" } }
  2. Execute o seguinte comando invoke:

    $ aws lambda invoke --function-name LambdaFunctionOverHttps \ --payload fileb://input.txt outputfile.txt

Criar uma API usando Amazon API Gateway

Nesta etapa, você associa sua função do Lambda a um método na API que você criou usando o Amazon API Gateway e testa a experiência completa. Ou seja, quando uma solicitação HTTP for enviada para um método de API, o Amazon API Gateway invocará sua função do Lambda.

Primeiro, você cria uma API (DynamoDBOperations) usando o Amazon API Gateway com um recurso (DynamoDBManager) e um método (POST). Você associar o método POST à sua função do Lambda. Em seguida, teste a experiência completa.

Criar a API

Execute o seguinte comando create-rest-api para criar a API DynamoDBOperations para este tutorial.

$ aws apigateway create-rest-api --name DynamoDBOperations { "id": "bs8fqo6bp0", "name": "DynamoDBOperations", "createdDate": 1539803980, "apiKeySource": "HEADER", "endpointConfiguration": { "types": [ "EDGE" ] } }

Salve o ID da API para uso em outros comandos. Você também precisa do ID do recurso raiz da API. Para obter o ID, execute o comando get-resources.

$ API=bs8fqo6bp0 $ aws apigateway get-resources --rest-api-id $API { "items": [ { "path": "/", "id": "e8kitthgdb" } ] }

No momento existe apenas o recurso raiz, porém mais recursos serão adicionados na próxima etapa.

Criar um recurso na API

Execute o seguinte comando create-resource para criar um recurso (DynamoDBManager) na API que você criou na seção anterior.

$ aws apigateway create-resource --rest-api-id $API --path-part DynamoDBManager \ --parent-id e8kitthgdb { "path": "/DynamoDBManager", "pathPart": "DynamoDBManager", "id": "resource-id", "parentId": "e8kitthgdb" }

Observe o ID na resposta. Esse é o ID do recurso DynamoDBManager que você criou.

Criar método POST no recurso

Execute o seguinte comando put-method para criar um método POST no recurso DynamoDBManager em sua API.

$ RESOURCE=iuig5w $ aws apigateway put-method --rest-api-id $API --resource-id $RESOURCE \ --http-method POST --authorization-type NONE { "apiKeyRequired": false, "httpMethod": "POST", "authorizationType": "NONE" }

Nós especificamos NONE para o parâmetro --authorization-type, o que significa que solicitações não autenticadas para esse método são compatíveis. Isso é aceitável para testes, mas em produção, você deve usar a autenticação baseada em chave ou função.

Definir a função do Lambda como o destino do método POST

Execute o comando a seguir para definir a função do Lambda como o ponto de integração para o método POST. Esse é o método que o Amazon API Gateway invoca quando você faz uma solicitação HTTP para o endpoint do método POST. Esse comando e outros usam ARNs que incluem seu ID de conta e região. Salve-os para variáveis (você pode encontrar o ID da sua conta na função ARN que você usou para criar a função).

$ REGION=us-east-2 $ ACCOUNT=123456789012 $ aws apigateway put-integration --rest-api-id $API --resource-id $RESOURCE \ --http-method POST --type AWS --integration-http-method POST \ --uri arn:aws:apigateway:$REGION:lambda:path/2015-03-31/functions/arn:aws:lambda:$REGION:$ACCOUNT:function:LambdaFunctionOverHttps/invocations { "type": "AWS", "httpMethod": "POST", "uri": "arn:aws:apigateway:us-east-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-2:123456789012:function:LambdaFunctionOverHttps/invocations", "passthroughBehavior": "WHEN_NO_MATCH", "timeoutInMillis": 29000, "cacheNamespace": "iuig5w", "cacheKeyParameters": [] }

O --integration-http-method é o método que o API Gateway usa para se comunicar com o AWS Lambda. O --uri é o identificador exclusivo do endpoint para o qual o Amazon API Gateway pode enviar a solicitação.

Defina o content-type da resposta POST do método de resposta e resposta de integração como JSON da seguinte forma:

  • Execute o comando a seguir para definir a reposta do método POST como JSON. Este é o tipo de resposta que o seu método de API retorna.

    $ aws apigateway put-method-response --rest-api-id $API \ --resource-id $RESOURCE --http-method POST \ --status-code 200 --response-models application/json=Empty { "statusCode": "200", "responseModels": { "application/json": "Empty" } }
  • Execute o comando a seguir para definir a resposta de integração do método POST como JSON. Este é o tipo de resposta que a função do Lambda retorna.

    $ aws apigateway put-integration-response --rest-api-id $API \ --resource-id $RESOURCE --http-method POST \ --status-code 200 --response-templates application/json="" { "statusCode": "200", "responseTemplates": { "application/json": null } }

Implantar a API

Nesta etapa, você implanta a API que você criou em um estágio chamado prod.

$ aws apigateway create-deployment --rest-api-id $API --stage-name prod { "id": "20vgsz", "createdDate": 1539820012 }

Conceder permissão de invocação à API

Agora que você tem uma API criada usando o Amazon API Gateway implantada, você pode testá-la. Primeiro, você precisa adicionar permissões para que o Amazon API Gateway possa invocar sua função do Lambda quando você enviar solicitações HTTP para o método POST.

Para fazer isso, você precisa adicionar uma permissão à política de permissões associada à sua função do Lambda. Execute o seguinte comando add-permission do AWS Lambda para conceder ao serviço do Amazon API Gateway as principais permissões (apigateway.amazonaws.com) para invocar sua função do Lambda (LambdaFunctionOverHttps).

$ aws lambda add-permission --function-name LambdaFunctionOverHttps \ --statement-id apigateway-test-2 --action lambda:InvokeFunction \ --principal apigateway.amazonaws.com \ --source-arn "arn:aws:execute-api:$REGION:$ACCOUNT:$API/*/POST/DynamoDBManager" { "Statement": "{\"Sid\":\"apigateway-test-2\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:us-east-2:123456789012:function:LambdaFunctionOverHttps\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:us-east-2:123456789012:mnh1yprki7/*/POST/DynamoDBManager\"}}}" }

Você deve conceder essa permissão para habilitar os testes (se você acessa o Amazon API Gateway e escolher Testar para testar o método de API, você precisa dessa permissão). Observe que o --source-arn especifica um caractere curinga (*) como o valor de estágio (indica apenas testes). Isso permite que você teste sem implantar a API.

nota

Se a sua função e a API estiverem em regiões diferentes, o identificador de região no ARN de origem deverá corresponder à região da função, e não à região da API.

Agora, execute o mesmo comando novamente, mas desta vez conceda à sua API implantada permissões para invocar a função do Lambda.

$ aws lambda add-permission --function-name LambdaFunctionOverHttps \ --statement-id apigateway-prod-2 --action lambda:InvokeFunction \ --principal apigateway.amazonaws.com \ --source-arn "arn:aws:execute-api:$REGION:$ACCOUNT:$API/prod/POST/DynamoDBManager" { "Statement": "{\"Sid\":\"apigateway-prod-2\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:us-east-2:123456789012:function:LambdaFunctionOverHttps\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:us-east-2:123456789012:mnh1yprki7/prod/POST/DynamoDBManager\"}}}" }

Você concede essa permissão para que sua API implantada tenha permissão para invocar a função do Lambda. Observe que o --source-arn especifica um prod que é o nome do estágio usado ao implantar a API.

Criar uma tabela do Amazon DynamoDB

Crie a tabela do DynamoDB usada pela função do Lambda.

Para criar uma tabela do DynamoDB

  1. Abra o console do DynamoDB.

  2. Escolha Create table.

  3. Crie uma tabela com as configurações a seguir.

    • Table name (Nome da tabela)lambda-apigateway

    • Primary key (Chave primária)id (string)

  4. Escolha Criar.

Acionar a função com uma solicitação HTTP

Nesta etapa, você está pronto para enviar uma solicitação HTTP para o endpoint do método POST. Você pode usar Curl ou um método (test-invoke-method) fornecido pelo Amazon API Gateway.

Você pode usar os comandos da CLI do Amazon API Gateway para enviar uma solicitação HTTP POST para o endpoint do recurso (DynamoDBManager). Como você implantou seu Amazon API Gateway, pode usar o Curl para invocar os métodos para a mesma operação.

A função do Lambda oferece suporte para o uso da operação create para criar um item em sua tabela do DynamoDB. Para solicitar essa operação, use o seguinte JSON:

exemplo create-item.json

{ "operation": "create", "tableName": "lambda-apigateway", "payload": { "Item": { "id": "1234ABCD", "number": 5 } } }

Salve a entrada de teste em um arquivo chamado create-item.json. Execute o comando test-invoke-method Amazon API Gateway para enviar a solicitação do método POST HTTP para o endpoint (DynamoDBManager) do recurso.

$ aws apigateway test-invoke-method --rest-api-id $API \ --resource-id $RESOURCE --http-method POST --path-with-query-string "" \ --body file://create-item.json

Ou então, você pode usar o seguinte comando Curl:

$ curl -X POST -d "{\"operation\":\"create\",\"tableName\":\"lambda-apigateway\",\"payload\":{\"Item\":{\"id\":\"1\",\"name\":\"Bob\"}}}" https://$API.execute-api.$REGION.amazonaws.com/prod/DynamoDBManager

Para enviar a solicitação para a operação echo suportada pela sua função do Lambda, você pode usar a seguinte carga de solicitação:

exemplo echo.json

{ "operation": "echo", "payload": { "somekey1": "somevalue1", "somekey2": "somevalue2" } }

Salve a entrada de teste em um arquivo chamado echo.json. Execute o comando test-invoke-method da CLI do Amazon API Gateway para enviar uma solicitação de método POST HTTP ao endpoint do recurso (DynamoDBManager) usando o JSON anterior no corpo na solicitação.

$ aws apigateway test-invoke-method --rest-api-id $API \ --resource-id $RESOURCE --http-method POST --path-with-query-string "" \ --body file://echo.json

Ou então, você pode usar o seguinte comando Curl:

$ curl -X POST -d "{\"operation\":\"echo\",\"payload\":{\"somekey1\":\"somevalue1\",\"somekey2\":\"somevalue2\"}}" https://$API.execute-api.$REGION.amazonaws.com/prod/DynamoDBManager