

# Tutorial: Crie uma API HTTP CRUD com o Lambda e o DynamoDB
<a name="http-api-dynamo-db"></a>

Neste tutorial, você cria uma API sem servidor que cria, lê, atualiza e exclui itens de uma tabela do DynamoDB. O DynamoDB é um serviço de banco de dados NoSQL totalmente gerenciado que proporciona uma performance rápida e previsível com escalabilidade contínua. Este tutorial leva aproximadamente 30 minutos para ser concluído, e você pode fazê-lo no [nível gratuito da AWS](https://aws.amazon.com/free/).

Primeiro, você cria uma tabela do [DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) usando o console do DynamoDB. Em seguida, você cria uma função do [Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) usando o console do AWS Lambda. Em seguida, crie uma API HTTP usando o console do API Gateway. Por fim, você testa a sua API.

Quando você invoca sua API HTTP, o API Gateway encaminha a solicitação para sua função do Lambda. A função do Lambda interage com o DynamoDB e retorna uma resposta ao API Gateway. O API Gateway retorna uma resposta para você.

![\[Visão geral da API HTTP que você cria neste tutorial.\]](http://docs.aws.amazon.com/pt_br/apigateway/latest/developerguide/images/ddb-crud.png)


Para concluir esse exercício, você precisa de uma conta da AWS e de um usuário do AWS Identity and Access Management com acesso ao console. Para obter mais informações, consulte [Configurar para usar o API Gateway](setting-up.md).

Neste tutorial, você usará o Console de gerenciamento da AWS. Para obter um modelo AWS SAM que cria essa API e todos os recursos relacionados, consulte [samples/http-dynamo-tutorial.zip](samples/http-dynamo-tutorial.zip).

**Topics**
+ [Etapa 1: Crie uma tabela do DynamoDB](#http-api-dynamo-db-create-table)
+ [Etapa 2: Criar uma função do Lambda](#http-api-dynamo-db-create-function)
+ [Etapa 3: Crie uma API HTTP](#http-api-dynamo-db-create-api)
+ [Etapa 4: Crie rotas](#http-api-dynamo-db-create-routes)
+ [Etapa 5: Crie uma integração](#http-api-dynamo-db-create-integration)
+ [Etapa 6: Anexe a sua integração às rotas](#http-api-dynamo-db-attach-integrations)
+ [Etapa 7: Teste a sua API](#http-api-dynamo-db-invoke-api)
+ [Etapa 8: Limpar](#http-api-dynamo-db-cleanup)
+ [Próximas etapas: Automatizar com AWS SAM ou CloudFormation](#http-api-dynamo-db-next-steps)

## Etapa 1: Crie uma tabela do DynamoDB
<a name="http-api-dynamo-db-create-table"></a>

Você usa uma tabela do [DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) para armazenar dados para a sua API. 

Cada item tem um ID exclusivo, que usamos como [partition key](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey) (chave de partição) para a tabela.

**Como criar uma tabela do DynamoDB**

1. Abra o console do DynamoDB em [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/).

1. Escolha **Create table**.

1. Em **Table name** (Nome da tabela), insira **http-crud-tutorial-items**.

1. Em **Partition key**, (Chave de partição), insira **id**.

1. Escolha **Create table**.

## Etapa 2: Criar uma função do Lambda
<a name="http-api-dynamo-db-create-function"></a>

Você cria uma função do [Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) para o backend da sua API. Essa função do Lambda cria, lê, atualiza e exclui itens do DynamoDB. A função usa [ events from API Gateway](http-api-develop-integrations-lambda.md#http-api-develop-integrations-lambda.proxy-format) (eventos do API Gateway) para definir como interagir com o DynamoDB. Para fins de simplicidade, este tutorial usa uma única função do Lambda. Como prática recomendada, você deve criar funções separadas para cada rota. Para obter mais informações, consulte [The Lambda monolith](https://serverlessland.com/content/service/lambda/guides/aws-lambda-operator-guide/monolith) (A aplicação monolítica do Lambda).

**Criar uma função do Lambda**

1. Abra o console do Lambda em [https://console.aws.amazon.com/lambda](https://console.aws.amazon.com/lambda)

1. Escolha **Create function** (Criar função).

1. Em **Function name** (Nome da função), insira **http-crud-tutorial-function**.

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

1. Em **Permissions** (Permissões), escolha **Change default execution role** (Alterar a função de execução padrão).

1. Selecione **Criar uma nova função a partir de modelos de política da AWS**.

1. Em **Role name** (Nome da função), insira **http-crud-tutorial-role**.

1. Em **Policy templates** (Modelos de políticas), escolha **Simple microservice permissions**. Esta política concede à função do Lambda permissão para interagir com o DynamoDB.
**nota**  
Este tutorial usa uma política gerenciada em prol da simplicidade. Como prática recomendada, você deve criar sua própria política do IAM para conceder as permissões mínimas necessárias.

1. Escolha **Create function** (Criar função).

1. Abra a função do Lambda no editor de código do console e substitua seu conteúdo pelo código a seguir. Escolha **Deploy** (Implantar) para atualizar a sua função.

------
#### [ Node.js ]

```
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import {
  DynamoDBDocumentClient,
  ScanCommand,
  PutCommand,
  GetCommand,
  DeleteCommand,
} from "@aws-sdk/lib-dynamodb";

const client = new DynamoDBClient({});

const dynamo = DynamoDBDocumentClient.from(client);

const tableName = "http-crud-tutorial-items";

export const handler = async (event, context) => {
  let body;
  let statusCode = 200;
  const headers = {
    "Content-Type": "application/json",
  };

  try {
    switch (event.routeKey) {
      case "DELETE /items/{id}":
        await dynamo.send(
          new DeleteCommand({
            TableName: tableName,
            Key: {
              id: event.pathParameters.id,
            },
          })
        );
        body = `Deleted item ${event.pathParameters.id}`;
        break;
      case "GET /items/{id}":
        body = await dynamo.send(
          new GetCommand({
            TableName: tableName,
            Key: {
              id: event.pathParameters.id,
            },
          })
        );
        body = body.Item;
        break;
      case "GET /items":
        body = await dynamo.send(
          new ScanCommand({ TableName: tableName })
        );
        body = body.Items;
        break;
      case "PUT /items":
        let requestJSON = JSON.parse(event.body);
        await dynamo.send(
          new PutCommand({
            TableName: tableName,
            Item: {
              id: requestJSON.id,
              price: requestJSON.price,
              name: requestJSON.name,
            },
          })
        );
        body = `Put item ${requestJSON.id}`;
        break;
      default:
        throw new Error(`Unsupported route: "${event.routeKey}"`);
    }
  } catch (err) {
    statusCode = 400;
    body = err.message;
  } finally {
    body = JSON.stringify(body);
  }

  return {
    statusCode,
    body,
    headers,
  };
};
```

------
#### [ Python ]

```
import json
import boto3
from decimal import Decimal

client = boto3.client('dynamodb')
dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table('http-crud-tutorial-items')
tableName = 'http-crud-tutorial-items'


def lambda_handler(event, context):
    print(event)
    body = {}
    statusCode = 200
    headers = {
        "Content-Type": "application/json"
    }

    try:
        if event['routeKey'] == "DELETE /items/{id}":
            table.delete_item(
                Key={'id': event['pathParameters']['id']})
            body = 'Deleted item ' + event['pathParameters']['id']
        elif event['routeKey'] == "GET /items/{id}":
            body = table.get_item(
                Key={'id': event['pathParameters']['id']})
            body = body["Item"]
            responseBody = [
                {'price': float(body['price']), 'id': body['id'], 'name': body['name']}]
            body = responseBody
        elif event['routeKey'] == "GET /items":
            body = table.scan()
            body = body["Items"]
            print("ITEMS----")
            print(body)
            responseBody = []
            for items in body:
                responseItems = [
                    {'price': float(items['price']), 'id': items['id'], 'name': items['name']}]
                responseBody.append(responseItems)
            body = responseBody
        elif event['routeKey'] == "PUT /items":
            requestJSON = json.loads(event['body'])
            table.put_item(
                Item={
                    'id': requestJSON['id'],
                    'price': Decimal(str(requestJSON['price'])),
                    'name': requestJSON['name']
                })
            body = 'Put item ' + requestJSON['id']
    except KeyError:
        statusCode = 400
        body = 'Unsupported route: ' + event['routeKey']
    body = json.dumps(body)
    res = {
        "statusCode": statusCode,
        "headers": {
            "Content-Type": "application/json"
        },
        "body": body
    }
    return res
```

------

## Etapa 3: Crie uma API HTTP
<a name="http-api-dynamo-db-create-api"></a>

A API HTTP fornece um endpoint de HTTP para sua função do Lambda. Nesta etapa, você cria uma API vazia. Nas etapas a seguir, você configura rotas e integrações para conectar a sua API e sua função do Lambda.



**Para criar uma API HTTP**

1. Inicie uma sessão no console do API Gateway em [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Escolha **Create API** (Criar API) e, em seguida, em **API HTTP** (API HTTP), escolha **Build** (Criar).

1. Em **API name (Nome da API)**, insira **http-crud-tutorial-api**.

1. Em **Tipo de endereço IP**, selecione **IPv4**.

1. Escolha **Próximo**.

1. Em **Configure routes** (Configurar rotas), escolha **Next** (Próximo) para ignorar a criação da rota. Você cria rotas mais tarde.

1. Analise o estágio que o API Gateway cria para você e escolha **Next** (Avançar). 

1. Escolha **Create** (Criar).

## Etapa 4: Crie rotas
<a name="http-api-dynamo-db-create-routes"></a>

As rotas são uma forma de enviar as solicitações de API recebidas a recursos de backend. As rotas consistem em duas partes: um método HTTP e um caminho de recurso, por exemplo, `GET /items`. Para esta API de exemplo, criamos quatro rotas:
+ `GET /items/{id}`
+ `GET /items`
+ `PUT /items`
+ `DELETE /items/{id}`

**Para criar rotas**

1. Inicie uma sessão no console do API Gateway em [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Selecione a API.

1. Selecione **Routes (Rotas)**.

1. Escolha **Create** (Criar).

1. Em **Método**, escolha **GET**.

1. Para o caminho, insira **/items/\$1id\$1**. O `{id}` no final do caminho é um parâmetro de caminho que o API Gateway recupera do caminho de solicitação quando um cliente faz uma solicitação.

1. Escolha **Create** (Criar).

1. Repita as etapas quatro a sete para `GET /items``DELETE /items/{id}` e `PUT /items`.

![\[A sua API tem rotas para GET /items, GET /items/{id}, DELETE /items/{id} e PUT /items.\]](http://docs.aws.amazon.com/pt_br/apigateway/latest/developerguide/images/ddb-create-routes.png)


## Etapa 5: Crie uma integração
<a name="http-api-dynamo-db-create-integration"></a>

Você cria uma integração para conectar uma rota aos recursos de backend. Para este exemplo de API, você cria uma integração do Lambda que usa para todas as rotas.

**Para criar uma integração**

1. Inicie uma sessão no console do API Gateway em [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Selecione a API.

1. Escolha **Integrations** (Integrações).

1. Escolha **Manage integrations** (Gerenciar integrações) e, em seguida, escolha **Create** (Criar).

1. Pule **Attach this integration to a route** (Anexar esta integração a uma rota). Você conclui isso em uma etapa posterior.

1. Em **Integration type** (Tipo de integração), escolha **Lambda function** (Função do Lambda).

1. Em **Lambda function** (Função do Lambda), insira **http-crud-tutorial-function**.

1. Escolha **Create** (Criar).

## Etapa 6: Anexe a sua integração às rotas
<a name="http-api-dynamo-db-attach-integrations"></a>

Para este exemplo de API, você usa a mesma integração do Lambda para todas as rotas. Depois de anexar a integração a todas as rotas da API, sua função do Lambda é invocada quando um cliente chama qualquer uma de suas rotas.



**Para anexar integrações a rotas**

1. Inicie uma sessão no console do API Gateway em [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Selecione a API.

1. Escolha **Integrations** (Integrações).

1. Escolha uma rota.

1. Em **Choose an existing integration** (Escolher uma integração existente), escolha **http-crud-tutorial-function**.

1. Escolha **Attach integration** (Anexar integração).

1. Repita as etapas quatro a seis para todas as rotas. 

Todas as rotas mostram que há uma integração com o AWS Lambda anexada.

![\[O console mostra o AWS Lambda em todas as rotas para indicar que sua integração está anexada.\]](http://docs.aws.amazon.com/pt_br/apigateway/latest/developerguide/images/ddb-attach-integrations.png)


Agora que você tem uma API HTTP com rotas e integrações, já pode testar a sua API.

## Etapa 7: Teste a sua API
<a name="http-api-dynamo-db-invoke-api"></a>

Para ter certeza de que a sua API está funcionando, use [curl](https://curl.se).

**Para obter a URL para invocar a sua API**

1. Inicie uma sessão no console do API Gateway em [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Selecione a API.

1. Observe o URL de invocação da sua API. Ela aparece em **Invoke URL** (Invocar URL) na página **Details** (Detalhes).  
![\[Depois de criar a API, o console mostra o URL de chamada da API.\]](http://docs.aws.amazon.com/pt_br/apigateway/latest/developerguide/images/ddb-invoke-url.png)

1. Copie a URL de invocação da sua API. 

   A URL completa se assemelha a `https://abcdef123.execute-api.us-west-2.amazonaws.com`. 

**Para criar ou atualizar um item**
+ Use o comando a seguir para criar ou atualizar um item. O comando inclui um corpo de solicitação com o ID, o preço e o nome do item.

  ```
  curl -X "PUT" -H "Content-Type: application/json" -d "{\"id\": \"123\", \"price\": 12345, \"name\": \"myitem\"}" https://abcdef123.execute-api.us-west-2.amazonaws.com/items
  ```

**Para obter todos os itens**
+ Use o comando a seguir para listar todos os itens.

  ```
  curl https://abcdef123.execute-api.us-west-2.amazonaws.com/items
  ```

**Para obter um item**
+ Use o comando a seguir para obter um item pelo seu ID.

  ```
  curl https://abcdef123.execute-api.us-west-2.amazonaws.com/items/123
  ```

**Para excluir um item**

1. Use o comando a seguir para excluir um item.

   ```
   curl -X "DELETE" https://abcdef123.execute-api.us-west-2.amazonaws.com/items/123
   ```

1. Obtenha todos os itens para verificar se o item foi excluído.

   ```
   curl https://abcdef123.execute-api.us-west-2.amazonaws.com/items
   ```

## Etapa 8: Limpar
<a name="http-api-dynamo-db-cleanup"></a>

Para evitar custos desnecessários, exclua os recursos que você criou como parte desse exercício de conceitos básicos. As etapas a seguir excluem sua API HTTP, sua função do Lambda e recursos associados.

**Como excluir uma tabela do DynamoDB**

1. Abra o console do DynamoDB em [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/).

1. Selecionar a sua tabela.

1. Selecione **Delete table (Excluir tabela)**.

1. Confirme a sua decisão e escolha **Delete** (Excluir).

**Para excluir uma API HTTP**

1. Inicie uma sessão no console do API Gateway em [https://console.aws.amazon.com/apigateway](https://console.aws.amazon.com/apigateway).

1. Na página **APIs** , selecione uma API. Escolha **Actions (Ações)** e, depois, escolha **Delete (Excluir)**.

1. Escolha **Delete** (Excluir).

**Para excluir uma função do Lambda**

1. Abra o console do Lambda em [https://console.aws.amazon.com/lambda](https://console.aws.amazon.com/lambda)

1. Na página **Functions**(Funções), selecione uma função. Escolha **Actions (Ações)** e, depois, escolha **Delete (Excluir)**.

1. Escolha **Delete** (Excluir).

**Para excluir um grupo de logs de uma função do Lambda**

1. No console do Amazon CloudWatch, abra a [página Log groups](https://console.aws.amazon.com/cloudwatch/home#logs:) (Grupos de log).

1. Na página **Log groups** (Grupos de log), selecione o grupo de log da função (`/aws/lambda/http-crud-tutorial-function`). Escolha **Actions** (Ações) e selecione **Delete log group** (Excluir grupo de log).

1. Escolha **Delete** (Excluir).

**Para excluir a função de execução de uma função do Lambda**

1. No console do AWS Identity and Access Management, abra a página [Roles](https://console.aws.amazon.com/iam/home?#/roles) (Funções).

1. Selecione a atribuição da função, por exemplo, `http-crud-tutorial-role`.

1. Selecione **Delete role (Excluir função)**.

1. Escolha **Sim, excluir**.

## Próximas etapas: Automatizar com AWS SAM ou CloudFormation
<a name="http-api-dynamo-db-next-steps"></a>

Você pode automatizar a criação e a limpeza dos recursos da AWS usando o CloudFormation ou o AWS SAM. Para obter um exemplo de modelo do AWS SAM para este tutorial, consulte [samples/http-dynamo-tutorial.zip](samples/http-dynamo-tutorial.zip).

Para ver modelos de exemplo do CloudFormation, consulte [modelos de exemplo do CloudFormation](https://github.com/awsdocs/amazon-api-gateway-developer-guide/tree/main/cloudformation-templates).