

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á.

# Criação de uma aplicação de postagem simples usando resolvedores do DynamoDB
<a name="tutorial-dynamodb-resolvers"></a>

**nota**  
Agora, oferecemos suporte principalmente ao runtime do APPSYNC\$1JS e sua documentação. Considere usar o runtime do APPSYNC\$1JS e seus guias disponíveis [aqui](https://docs.aws.amazon.com/appsync/latest/devguide/tutorials-js.html).

Este tutorial mostra como você pode trazer suas próprias tabelas do Amazon DynamoDB e conectá-las AWS AppSync a uma API do GraphQL.

Você pode permitir o AWS AppSync provisionamento de recursos do DynamoDB em seu nome. Ou, se preferir, você pode conectar as tabelas existentes a um esquema do GraphQL criando uma fonte de dados e um resolvedor. Em ambos os casos, você poderá ler e gravar no banco de dados do DynamoDB por meio de instruções do GraphQL e assinar dados em tempo real.

Existem etapas de configuração específicas que precisam ser concluídas para que as instruções do GraphQL sejam traduzidas para operações do DynamoDB e para que as respostas sejam traduzidas novamente para o GraphQL. Esse tutorial descreve o processo de configuração por meio de vários cenários reais e padrões de acesso aos dados.

## Configuração de tabelas do DynamoDB
<a name="setting-up-your-ddb-tables"></a>

Para começar este tutorial, primeiro você precisa seguir as etapas abaixo para provisionar AWS recursos.

1. Provisione AWS recursos usando o seguinte AWS CloudFormation modelo na CLI:

   ```
   aws cloudformation create-stack \
       --stack-name AWSAppSyncTutorialForAmazonDynamoDB \
       --template-url https://s3.us-west-2.amazonaws.com/awsappsync/resources/dynamodb/AmazonDynamoDBCFTemplate.yaml \
       --capabilities CAPABILITY_NAMED_IAM
   ```

   Como alternativa, você pode lançar a seguinte CloudFormation pilha na região Oeste dos EUA 2 (Oregon) em sua conta. AWS 

   [https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?templateURL=https://s3.us-west-2.amazonaws.com/awsappsync/resources/dynamodb/AmazonDynamoDBCFTemplate.yaml](https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?templateURL=https://s3.us-west-2.amazonaws.com/awsappsync/resources/dynamodb/AmazonDynamoDBCFTemplate.yaml)

   Isso cria o seguinte:
   + Uma tabela do DynamoDB chamada `AppSyncTutorial-Post` que armazenará os dados de `Post`.
   + Uma função do IAM e uma política gerenciada do IAM associada AWS AppSync para permitir a interação com a `Post` tabela.

1. Para ver mais detalhes sobre a pilha e os recursos criados, execute o seguinte comando da CLI:

   ```
   aws cloudformation describe-stacks --stack-name AWSAppSyncTutorialForAmazonDynamoDB
   ```

1. Para excluir os recursos mais tarde, execute o seguinte:

   ```
   aws cloudformation delete-stack --stack-name AWSAppSyncTutorialForAmazonDynamoDB
   ```

## Criação da API GraphQL
<a name="creating-your-graphql-api"></a>

Para criar a API GraphQL em: AWS AppSync

1. Faça login no Console de gerenciamento da AWS e abra o [AppSync console](https://console.aws.amazon.com/appsync/).

   1. No **APIs painel**, escolha **Criar API**.

1. Na janela **Personalizar sua API ou importar a partir do Amazon DynamoDB**, escolha **Criar a partir do zero**.

   1. Escolha **Iniciar** à direita da mesma janela.

1. No campo **Nome da API**, defina o nome da API para `AWSAppSyncTutorial`.

1. Escolha **Criar**.

O AWS AppSync console cria uma nova API GraphQL para você usando o modo de autenticação por chave de API. Você pode usar o console para configurar o restante da API GraphQL e executar consultas nela durante o restante desse tutorial.

## Definição de uma API Post básica
<a name="defining-a-basic-post-api"></a>

Agora que você criou uma API AWS AppSync GraphQL, você pode configurar um esquema básico que permite a criação, recuperação e exclusão básicas de dados de postagem.

1. Faça login no Console de gerenciamento da AWS e abra o [AppSync console](https://console.aws.amazon.com/appsync/).

   1. No **APIs painel**, escolha a API que você acabou de criar.

1. Na **barra lateral**, escolha **Esquema**.

   1. No painel **Esquema**, substitua o conteúdo pelo seguinte código:

     ```
     schema {
         query: Query
         mutation: Mutation
     }
     
     type Query {
         getPost(id: ID): Post
     }
     
     type Mutation {
         addPost(
             id: ID!
             author: String!
             title: String!
             content: String!
             url: String!
         ): Post!
     }
     
     type Post {
         id: ID!
         author: String
         title: String
         content: String
         url: String
         ups: Int!
         downs: Int!
         version: Int!
     }
     ```

1. Escolha **Salvar**.

Esse esquema define um tipo `Post` e operações para adicionar e obter objetos `Post`.

## Configuração da fonte de dados para as tabelas do DynamoDB
<a name="configuring-the-data-source-for-the-ddb-tables"></a>

Em seguida, vincule as consultas e mutações definidas no esquema à tabela `AppSyncTutorial-Post` do DynamoDB.

Primeiro, AWS AppSync precisa estar atento às suas tabelas. Faça isso ao configurar uma fonte de dados no AWS AppSync:

1. Faça login no Console de gerenciamento da AWS e abra o [AppSync console](https://console.aws.amazon.com/appsync/).

   1. No **APIs painel**, escolha sua API GraphQL.

   1. Na **barra lateral**, escolha **Fontes de dados**.

1. Escolha **Criar fonte de dados**.

   1. Para **Nome da fonte de dados**, insira em `PostDynamoDBTable`. 

   1. Para o **tipo de fonte de dados**, escolha **Tabela do Amazon DynamoDB**.

   1. Para **Região**, escolha **US-WEST-2**.

   1. Em **Nome da tabela**, escolha a tabela **AppSyncTutorial-Post DynamoDB**.

   1. Crie um perfil do IAM (recomendado) ou escolha uma função existente que tenha permissão do IAM `lambda:invokeFunction`. Os perfis existentes precisam de uma política de confiança, conforme explicado na seção [Anexar uma fonte de dados](attaching-a-data-source.md). 

      Veja a seguir um exemplo de política do IAM que tem as permissões necessárias para executar as operações no recurso:

------
#### [ JSON ]

****  

      ```
      { 
           "Version":"2012-10-17",		 	 	  
           "Statement": [ 
               { 
                   "Effect": "Allow", 
                   "Action": [ "lambda:invokeFunction" ], 
                   "Resource": [ 
                       "arn:aws:lambda:us-east-1:111122223333:function:myFunction", 
                       "arn:aws:lambda:us-east-1:111122223333:function:myFunction:*" 
                   ] 
               } 
           ] 
       }
      ```

------

1. Escolha **Criar**.

## Configurando o resolvedor AddPost (DynamoDB) PutItem
<a name="setting-up-the-addpost-resolver-dynamodb-putitem"></a>

**Depois de conhecer AWS AppSync a tabela do DynamoDB, você pode vinculá-la a consultas e mutações individuais definindo Resolvers.** O primeiro resolvedor criado é o resolvedor `addPost`, que permite criar uma publicação na tabela `AppSyncTutorial-Post` do DynamoDB.

Um resolvedor tem os seguintes componentes:
+ A local no esquema do GraphQL para anexar o resolvedor. Nesse caso, você está configurando um resolvedor no campo `addPost` no tipo `Mutation`. Esse resolvedor será invocado quando o chamador chamar `mutation { addPost(...){...} }`.
+ A fonte de dados a ser usada para esse resolvedor. Nesse caso, você deseja usar a fonte de dados `PostDynamoDBTable` definida anteriormente, para que possa adicionar entradas na tabela do DynamoDB `AppSyncTutorial-Post`.
+ O modelo de mapeamento da solicitação. O objetivo do modelo de mapeamento de solicitações é pegar a solicitação recebida do chamador e traduzi-la em instruções AWS AppSync para execução no DynamoDB.
+ O modelo de mapeamento da resposta. O trabalho do modelo de mapeamento da resposta é receber a resposta do DynamoDB e traduzi-la de volta para algo esperado pelo GraphQL. Isso é útil se a forma dos dados no DynamoDB for diferente para o tipo `Post` no GraphQL, mas, nesse caso, elas têm a mesma forma, portanto basta transmitir os dados.

Como configurar o resolvedor :

1. Faça login no Console de gerenciamento da AWS e abra o [AppSync console](https://console.aws.amazon.com/appsync/).

   1. No **APIs painel**, escolha sua API GraphQL.

   1. Na **barra lateral**, escolha **Fontes de dados**.

1. Escolha **Criar fonte de dados**.

   1. Para **Nome da fonte de dados**, insira em `PostDynamoDBTable`. 

   1. Para o **tipo de fonte de dados**, escolha **Tabela do Amazon DynamoDB**.

   1. Para **Região**, escolha **US-WEST-2**.

   1. Em **Nome da tabela**, escolha a tabela **AppSyncTutorial-Post DynamoDB**.

   1. Crie um perfil do IAM (recomendado) ou escolha uma função existente que tenha permissão do IAM `lambda:invokeFunction`. Os perfis existentes precisam de uma política de confiança, conforme explicado na seção [Anexar uma fonte de dados](attaching-a-data-source.md). 

      Veja a seguir um exemplo de política do IAM que tem as permissões necessárias para executar as operações no recurso:

------
#### [ JSON ]

****  

      ```
      { 
           "Version":"2012-10-17",		 	 	  
           "Statement": [ 
               { 
                   "Effect": "Allow", 
                   "Action": [ "lambda:invokeFunction" ], 
                   "Resource": [ 
                       "arn:aws:lambda:us-west-2:123456789012:function:myFunction", 
                       "arn:aws:lambda:us-west-2:123456789012:function:myFunction:*" 
                   ] 
               } 
           ] 
       }
      ```

------

1. Escolha **Criar**.

1. Escolha a guia **Esquema**.

1. No painel **Tipos de dados** à direita, encontre o campo **addPost** no tipo **Mutação** e, em seguida, escolha **Anexar**.

1. No **menu Ação**, escolha **Atualizar runtime** e selecione **Resolvedor de unidade (somente VTL)**.

1. Em **Data source name (Nome da fonte de dados)**, escolha **PostDynamoDBTable**.

1. Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

   ```
   {
       "version" : "2017-02-28",
       "operation" : "PutItem",
       "key" : {
           "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
       },
       "attributeValues" : {
           "author" : $util.dynamodb.toDynamoDBJson($context.arguments.author),
           "title" : $util.dynamodb.toDynamoDBJson($context.arguments.title),
           "content" : $util.dynamodb.toDynamoDBJson($context.arguments.content),
           "url" : $util.dynamodb.toDynamoDBJson($context.arguments.url),
           "ups" : { "N" : 1 },
           "downs" : { "N" : 0 },
           "version" : { "N" : 1 }
       }
   }
   ```

   **Observação:** um *tipo* é especificado em todas as chaves e valores de atributo. Por exemplo, defina o campo `author` para `{ "S" : "${context.arguments.author}" }`. A `S` parte indica para o DynamoDB AWS AppSync e para o DynamoDB que o valor será um valor de string. O valor real é preenchido a partir do argumento `author`. Da mesma forma, o campo `version` é um campo de número pois ele usa `N` para o tipo. Finalmente, você também está inicializando os campos `ups`, `downs` e `version`.

   Neste tutorial, você especificou que o `ID!` tipo GraphQL, que indexa o novo item inserido no DynamoDB, vem como parte dos argumentos do cliente. AWS AppSync vem com um utilitário para geração automática de ID`$utils.autoId()`, chamado que você também poderia ter usado na forma de`"id" : { "S" : "${$utils.autoId()}" }`. Depois, basta deixar o `id: ID!` fora da definição do esquema de `addPost()` e ele seria inserido automaticamente. Você não usará essa técnica para esse tutorial, mas deve considerá-la como uma das melhores práticas ao gravar em tabelas do DynamoDB.

   Para obter mais informações sobre os modelos de mapeamento, consulte a documentação de referência [Visão geral do modelo de mapeamento do resolvedor](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview). Para obter mais informações sobre mapeamento de GetItem solicitações, consulte a documentação de [GetItem](aws-appsync-resolver-mapping-template-reference-dynamodb-getitem.md)referência. Para obter mais informações sobre os tipos, consulte a documentação de referência [Mapeamento da solicitação](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md).

1. Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

   ```
   $utils.toJson($context.result)
   ```

    **Observação:** como o formato dos dados na tabela `AppSyncTutorial-Post` corresponde exatamente ao formato do tipo `Post` no GraphQL, o modelo de mapeamento da resposta apenas transmite os resultados diretamente. Observe também que todos os exemplos desse tutorial usam o mesmo modelo de mapeamento da resposta, portanto você só cria um arquivo.

1. Escolha **Salvar**.

### Chamar a API para adicionar uma publicação
<a name="call-the-api-to-add-a-post"></a>

Agora que o resolvedor está configurado, é AWS AppSync possível traduzir uma `addPost` mutação recebida em uma operação do DynamoDB. PutItem Agora você pode executar uma mutação para colocar algo na tabela.
+ Escolha a guia **Consultas**.
+ No painel **Consultas**, cole a seguinte mutação:

  ```
  mutation addPost {
    addPost(
      id: 123
      author: "AUTHORNAME"
      title: "Our first post!"
      content: "This is our first post."
      url: "https://aws.amazon.com/appsync/"
    ) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).
+ Os resultados da publicação recém-criada devem aparecer no painel de resultados à direita do painel de consulta. A aparência deve ser semelhante à seguinte:

  ```
  {
    "data": {
      "addPost": {
        "id": "123",
        "author": "AUTHORNAME",
        "title": "Our first post!",
        "content": "This is our first post.",
        "url": "https://aws.amazon.com/appsync/",
        "ups": 1,
        "downs": 0,
        "version": 1
      }
    }
  }
  ```

Veja o que aconteceu:
+ AWS AppSync recebeu uma solicitação de `addPost` mutação.
+ AWS AppSync pegou a solicitação e o modelo de mapeamento da solicitação e gerou um documento de mapeamento da solicitação. Isso teria a seguinte aparência:

  ```
  {
      "version" : "2017-02-28",
      "operation" : "PutItem",
      "key" : {
          "id" : { "S" : "123" }
      },
      "attributeValues" : {
          "author": { "S" : "AUTHORNAME" },
          "title": { "S" : "Our first post!" },
          "content": { "S" : "This is our first post." },
          "url": { "S" : "https://aws.amazon.com/appsync/" },
          "ups" : { "N" : 1 },
          "downs" : { "N" : 0 },
          "version" : { "N" : 1 }
      }
  }
  ```
+ AWS AppSync usou o documento de mapeamento da solicitação para gerar e executar uma solicitação do `PutItem` DynamoDB.
+ AWS AppSync pegou os resultados da `PutItem` solicitação e os converteu de volta em tipos GraphQL.

  ```
  {
      "id" : "123",
      "author": "AUTHORNAME",
      "title": "Our first post!",
      "content": "This is our first post.",
      "url": "https://aws.amazon.com/appsync/",
      "ups" : 1,
      "downs" : 0,
      "version" : 1
  }
  ```
+ Os transmitiu por meio do documento de mapeamento da resposta, sem alterações.
+ Retornou o objeto recém-criado na resposta do GraphQL.

## Configurando o GetPost Resolver (DynamoDB) GetItem
<a name="setting-up-the-getpost-resolver-ddb-getitem"></a>

Agora que você pode adicionar dados à tabela `AppSyncTutorial-Post` do DynamoDB, é necessário configurar a consulta `getPost` para que ela possa recuperar esses dados da tabela `AppSyncTutorial-Post`. Para fazer isso, vamos configurar outro resolvedor.
+ Escolha a guia **Esquema**.
+ No painel **Tipos de dados** à direita, encontre o campo **getPost** no tipo **Consulta** e, em seguida, escolha **Anexar**.
+ No **menu Ação**, escolha **Atualizar runtime** e selecione **Resolvedor de unidade (somente VTL)**.
+ Em **Data source name (Nome da fonte de dados)**, escolha **PostDynamoDBTable**.
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  {
      "version" : "2017-02-28",
      "operation" : "GetItem",
      "key" : {
          "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
      }
  }
  ```
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  $utils.toJson($context.result)
  ```
+ Escolha **Salvar**.

### Chamar a API para obter uma publicação
<a name="call-the-api-to-get-a-post"></a>

Agora, o resolvedor foi configurado e AWS AppSync sabe como traduzir uma `getPost` consulta recebida em uma operação do DynamoDB. `GetItem` Agora é possível executar uma consulta para recuperar a publicação criada anteriormente.
+ Escolha a guia **Consultas**.
+ No painel **Consultas**, cole o seguinte:

  ```
  query getPost {
    getPost(id:123) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).
+ A publicação recuperada do DynamoDB deve aparecer no painel de resultados à direita do painel de consulta. A aparência deve ser semelhante à seguinte:

  ```
  {
    "data": {
      "getPost": {
        "id": "123",
        "author": "AUTHORNAME",
        "title": "Our first post!",
        "content": "This is our first post.",
        "url": "https://aws.amazon.com/appsync/",
        "ups": 1,
        "downs": 0,
        "version": 1
      }
    }
  }
  ```

Veja o que aconteceu:
+ AWS AppSync recebeu uma solicitação `getPost` de consulta.
+ AWS AppSync pegou a solicitação e o modelo de mapeamento da solicitação e gerou um documento de mapeamento da solicitação. Isso teria a seguinte aparência:

  ```
  {
      "version" : "2017-02-28",
      "operation" : "GetItem",
      "key" : {
          "id" : { "S" : "123" }
      }
  }
  ```
+ AWS AppSync usou o documento de mapeamento da solicitação para gerar e executar uma solicitação do GetItem DynamoDB.
+ AWS AppSync pegou os resultados da `GetItem` solicitação e os converteu de volta para os tipos GraphQL.

  ```
  {
      "id" : "123",
      "author": "AUTHORNAME",
      "title": "Our first post!",
      "content": "This is our first post.",
      "url": "https://aws.amazon.com/appsync/",
      "ups" : 1,
      "downs" : 0,
      "version" : 1
  }
  ```
+ Os transmitiu por meio do documento de mapeamento da resposta, sem alterações.
+ Retornou o objeto recuperado na resposta.

Como alternativa, utilize o exemplo a seguir:

```
query getPost {
  getPost(id:123) {
    id
    author
    title
  }
}
```

Se sua consulta `getPost` precisar apenas de `id`, `author` e `title`, você poderá alterar seu modelo de mapeamento da solicitação para usar expressões de projeção para especificar apenas os atributos que deseja da tabela do DynamoDB para evitar transferência desnecessária de dados do DynamoDB para AWS AppSync. Por exemplo, o modelo de mapeamento da solicitação pode se parecer com o trecho abaixo:

```
{
    "version" : "2017-02-28",
    "operation" : "GetItem",
    "key" : {
        "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
    },
    "projection" : {
     "expression" : "#author, id, title",
     "expressionNames" : { "#author" : "author"}
    }
}
```

## Criar uma mutação UpdatePost (DynamoDB) UpdateItem
<a name="create-an-updatepost-mutation-ddb-updateitem"></a>

Até agora, você pode criar e recuperar objetos `Post` no DynamoDB. Depois, você configurará uma nova mutação para que possamos atualizar o objeto. Você fará isso usando a operação do UpdateItem DynamoDB.
+ Escolha a guia **Esquema**.
+ No painel **Esquema**, modifique o tipo `Mutation` para adicionar uma nova mutação `updatePost` da seguinte forma:

  ```
  type Mutation {
      updatePost(
          id: ID!,
          author: String!,
          title: String!,
          content: String!,
          url: String!
      ): Post
      addPost(
          author: String!
          title: String!
          content: String!
          url: String!
      ): Post!
  }
  ```
+ Escolha **Salvar**.
+ No painel **Tipos de dados** à direita, encontre o campo **updatePost** recém-criado no tipo **Mutação** e, em seguida, escolha **Anexar**.
+ No **menu Ação**, escolha **Atualizar runtime** e selecione **Resolvedor de unidade (somente VTL)**.
+ Em **Data source name (Nome da fonte de dados)**, escolha **PostDynamoDBTable**.
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  {
      "version" : "2017-02-28",
      "operation" : "UpdateItem",
      "key" : {
          "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
      },
      "update" : {
          "expression" : "SET author = :author, title = :title, content = :content, #url = :url ADD version :one",
          "expressionNames": {
              "#url" : "url"
          },
          "expressionValues": {
              ":author" : $util.dynamodb.toDynamoDBJson($context.arguments.author),
              ":title" : $util.dynamodb.toDynamoDBJson($context.arguments.title),
              ":content" : $util.dynamodb.toDynamoDBJson($context.arguments.content),
              ":url" : $util.dynamodb.toDynamoDBJson($context.arguments.url),
              ":one" : { "N": 1 }
          }
      }
  }
  ```

   **Observação:** esse resolvedor está usando o UpdateItem DynamoDB, que é significativamente diferente da operação. PutItem Em vez de escrever o item inteiro, você está apenas pedindo ao DynamoDB para atualizar determinados atributos. Isso é feito usando expressões de atualização do DynamoDB. A expressão em si é especificada no campo `expression` na seção `update`. Ela diz para definir o `author`, o `title`, o `content` e os atributos de url e, em seguida, incrementar o campo `version`. Os valores a serem usados não aparecem na expressão em si; a expressão tem espaços reservados com nomes que começam com "dois pontos", que são definidos no campo `expressionValues`. Finalmente, o DynamoDB tem palavras reservadas que não podem aparecer no `expression`. Por exemplo, `url` é uma palavra reservada, então, para atualizar o campo `url` é possível usar espaços reservados de nome e defini-los no campo `expressionNames`.

  Para obter mais informações sobre mapeamento de `UpdateItem` solicitações, consulte a documentação de [UpdateItem](aws-appsync-resolver-mapping-template-reference-dynamodb-updateitem.md)referência. Para obter mais informações sobre como escrever expressões de atualização, consulte a documentação do [ UpdateExpressions DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html).
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  $utils.toJson($context.result)
  ```

### Chamar a API para atualizar uma publicação
<a name="call-the-api-to-update-a-post"></a>

Agora, o resolvedor foi configurado e AWS AppSync sabe como traduzir uma `update` mutação recebida em uma operação do DynamoDB. `Update` Agora você pode executar uma mutação para atualizar o item escrito anteriormente.
+ Escolha a guia **Consultas**.
+ No painel **Consultas**, cole a seguinte mutação. Também será necessário atualizar o argumento `id` para o valor anotado anteriormente.

  ```
  mutation updatePost {
    updatePost(
      id:"123"
      author: "A new author"
      title: "An updated author!"
      content: "Now with updated content!"
      url: "https://aws.amazon.com/appsync/"
    ) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).
+ A publicação atualizada no DynamoDB deve aparecer no painel de resultados à direita do painel de consulta. A aparência deve ser semelhante à seguinte:

  ```
  {
    "data": {
      "updatePost": {
        "id": "123",
        "author": "A new author",
        "title": "An updated author!",
        "content": "Now with updated content!",
        "url": "https://aws.amazon.com/appsync/",
        "ups": 1,
        "downs": 0,
        "version": 2
      }
    }
  }
  ```

Neste exemplo, os `downs` campos `ups` e não foram modificados porque o modelo de mapeamento de solicitações não AWS AppSync solicitou que o DynamoDB fizesse nada com esses campos. Além disso, o `version` campo foi incrementado em 1 porque você pediu ao AWS AppSync DynamoDB que adicionasse 1 ao campo. `version`

## Modificando o UpdatePost Resolver (DynamoDB) UpdateItem
<a name="modifying-the-updatepost-resolver-dynamodb-updateitem"></a>

Esse é um bom início para a mutação `updatePost`, mas tem dois problemas principais:
+ Se quiser atualizar apenas um único campo, é necessário atualizar todos os campos.
+ Se duas pessoas estiverem modificando o objeto, possivelmente haverá perda de informações.

Para resolver esses problemas, você modificará a mutação `updatePost` para modificar apenas os argumentos que foram especificados na solicitação e, depois, adicionará uma condição à operação `UpdateItem`.

1. Escolha a guia **Esquema**.

1. No painel **Esquema**, modifique o campo `updatePost` no tipo `Mutation` para remover os pontos de exclamação dos argumentos `author`, `title`, `content` e `url`, sem se esquecer de deixar o campo `id` como está. Isso os tornará argumento opcional. Além disso, adicione um novo argumento `expectedVersion` obrigatório.

   ```
   type Mutation {
       updatePost(
           id: ID!,
           author: String,
           title: String,
           content: String,
           url: String,
           expectedVersion: Int!
       ): Post
       addPost(
           author: String!
           title: String!
           content: String!
           url: String!
       ): Post!
   }
   ```

1. Escolha **Salvar**.

1. No painel **Tipos de dados**, encontre o campo **updatePost** no tipo **Mutação**.

1. Escolha **PostDynamoDBTable**abrir o resolvedor existente.

1. Em **Configurar o modelo de mapeamento da solicitação**, modifique o modelo de mapeamento da solicitação da seguinte forma:

   ```
   {
       "version" : "2017-02-28",
       "operation" : "UpdateItem",
       "key" : {
           "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
       },
   
       ## Set up some space to keep track of things you're updating **
       #set( $expNames  = {} )
       #set( $expValues = {} )
       #set( $expSet = {} )
       #set( $expAdd = {} )
       #set( $expRemove = [] )
   
       ## Increment "version" by 1 **
       $!{expAdd.put("version", ":one")}
       $!{expValues.put(":one", { "N" : 1 })}
   
       ## Iterate through each argument, skipping "id" and "expectedVersion" **
       #foreach( $entry in $context.arguments.entrySet() )
           #if( $entry.key != "id" && $entry.key != "expectedVersion" )
               #if( (!$entry.value) && ("$!{entry.value}" == "") )
                   ## If the argument is set to "null", then remove that attribute from the item in DynamoDB **
   
                   #set( $discard = ${expRemove.add("#${entry.key}")} )
                   $!{expNames.put("#${entry.key}", "$entry.key")}
               #else
                   ## Otherwise set (or update) the attribute on the item in DynamoDB **
   
                   $!{expSet.put("#${entry.key}", ":${entry.key}")}
                   $!{expNames.put("#${entry.key}", "$entry.key")}
                   $!{expValues.put(":${entry.key}", { "S" : "${entry.value}" })}
               #end
           #end
       #end
   
       ## Start building the update expression, starting with attributes you're going to SET **
       #set( $expression = "" )
       #if( !${expSet.isEmpty()} )
           #set( $expression = "SET" )
           #foreach( $entry in $expSet.entrySet() )
               #set( $expression = "${expression} ${entry.key} = ${entry.value}" )
               #if ( $foreach.hasNext )
                   #set( $expression = "${expression}," )
               #end
           #end
       #end
   
       ## Continue building the update expression, adding attributes you're going to ADD **
       #if( !${expAdd.isEmpty()} )
           #set( $expression = "${expression} ADD" )
           #foreach( $entry in $expAdd.entrySet() )
               #set( $expression = "${expression} ${entry.key} ${entry.value}" )
               #if ( $foreach.hasNext )
                   #set( $expression = "${expression}," )
               #end
           #end
       #end
   
       ## Continue building the update expression, adding attributes you're going to REMOVE **
       #if( !${expRemove.isEmpty()} )
           #set( $expression = "${expression} REMOVE" )
   
           #foreach( $entry in $expRemove )
               #set( $expression = "${expression} ${entry}" )
               #if ( $foreach.hasNext )
                   #set( $expression = "${expression}," )
               #end
           #end
       #end
   
       ## Finally, write the update expression into the document, along with any expressionNames and expressionValues **
       "update" : {
           "expression" : "${expression}"
           #if( !${expNames.isEmpty()} )
               ,"expressionNames" : $utils.toJson($expNames)
           #end
           #if( !${expValues.isEmpty()} )
               ,"expressionValues" : $utils.toJson($expValues)
           #end
       },
   
       "condition" : {
           "expression"       : "version = :expectedVersion",
           "expressionValues" : {
               ":expectedVersion" : $util.dynamodb.toDynamoDBJson($context.arguments.expectedVersion)
           }
       }
   }
   ```

1. Escolha **Salvar**.

Este modelo é um dos exemplos mais complexos. Ele demonstra a potência e a flexibilidade dos modelos de mapeamento. Ele percorre todos os argumentos, ignorando `id` e `expectedVersion`. Se o argumento for definido como algo, ele solicitará que o DynamoDB AWS AppSync atualize esse atributo no objeto no DynamoDB. Se o atributo for definido como nulo, ele AWS AppSync solicitará que o DynamoDB remova esse atributo do objeto de postagem. Se um argumento não foi especificado, nada será feito com o atributo. Ele também incrementa o campo `version`.

Além disso, há uma nova seção `condition`. Uma expressão de condição permite que você diga ao AWS AppSync DynamoDB se a solicitação deve ou não ser bem-sucedida com base no estado do objeto que já está no DynamoDB antes da execução da operação. Nesse caso, você deseja que a solicitação `UpdateItem` seja bem-sucedida apenas se o campo `version` do item atualmente no DynamoDB corresponder ao argumento `expectedVersion`.

Para obter mais informações sobre as expressões de condições, consulte a documentação de referência [Expressões de condições](aws-appsync-resolver-mapping-template-reference-dynamodb-condition-expressions.md).

### Chamar a API para atualizar uma publicação
<a name="id1"></a>

Vamos tentar atualizar o objeto `Post` com o novo resolvedor:
+ Escolha a guia **Consultas**.
+ No painel **Consultas**, cole a mutação a seguir. Também será necessário atualizar o argumento `id` para o valor anotado anteriormente.

  ```
  mutation updatePost {
    updatePost(
      id:123
      title: "An empty story"
      content: null
      expectedVersion: 2
    ) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).
+ A publicação atualizada no DynamoDB deve aparecer no painel de resultados à direita do painel de consulta. A aparência deve ser semelhante à seguinte:

  ```
  {
    "data": {
      "updatePost": {
        "id": "123",
        "author": "A new author",
        "title": "An empty story",
        "content": null,
        "url": "https://aws.amazon.com/appsync/",
        "ups": 1,
        "downs": 0,
        "version": 3
      }
    }
  }
  ```

Nessa solicitação, você pediu ao AWS AppSync DynamoDB que atualizasse somente `title` o campo e. `content` Ele ignorou todos os outros campos (além de incrementar o campo `version`). Definiu-se o atributo `title` para um novo valor e o atributo `content` foi removido da publicação. Os campos `author`, `url`, `ups` e `downs` foram mantidos.

Tente executar a solicitação de mutação novamente, deixando a solicitação exatamente como está. Você verá uma resposta semelhante à seguinte:

```
{
  "data": {
    "updatePost": null
  },
  "errors": [
    {
      "path": [
        "updatePost"
      ],
      "data": {
        "id": "123",
        "author": "A new author",
        "title": "An empty story",
        "content": null,
        "url": "https://aws.amazon.com/appsync/",
        "ups": 1,
        "downs": 0,
        "version": 3
      },
      "errorType": "DynamoDB:ConditionalCheckFailedException",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "message": "The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ)"
    }
  ]
}
```

A solicitação falha pois a expressão de condição é avaliada como falsa:
+ Na primeira vez que você executou a solicitação, o valor do campo `version` da publicação no DynamoDB era `2`, que correspondia ao argumento `expectedVersion`. A solicitação foi bem-sucedida, o que significa que o campo `version` foi incrementado no DynamoDB para `3`.
+ Na segunda vez que a solicitação foi executada, o valor do campo `version` da publicação no DynamoDB era `3`, que não correspondeu ao argumento `expectedVersion`.

Esse padrão é geralmente chamado de *bloqueio positivo*.

Um recurso de um resolvedor do AWS AppSync DynamoDB é que ele retorna o valor atual do objeto post no DynamoDB. Encontre isso no campo `data` na seção `errors` da resposta do GraphQL. O aplicativo pode usar essas informações para decidir como deve continuar. Nesse caso, é possível ver que o campo `version` do objeto no DynamoDB está definido como `3`; portanto, podemos apenas atualizar o argumento `expectedVersion` para `3` e a solicitação teria êxito novamente.

Para obter mais informações sobre o tratamento de falhas da verificação de condição, consulte a documentação de referência do modelo de mapeamento [Expressões de condições](aws-appsync-resolver-mapping-template-reference-dynamodb-condition-expressions.md).

## Crie mutações UpVotePost e DownVotePost (DynamoDB) UpdateItem
<a name="create-upvotepost-and-downvotepost-mutations-ddb-updateitem"></a>

O tipo `Post` tem campos `ups` e `downs` para habilitar o registro de votos positivos e negativos, mas até agora a API não permite fazer nada com eles. Vamos adicionar algumas mutações para permitir votos positivos e negativos nas publicações.
+ Escolha a guia **Esquema**.
+ No painel **Esquema**, modifique o tipo `Mutation` para adicionar novas mutações `upvotePost` e `downvotePost` da seguinte forma:

  ```
  type Mutation {
      upvotePost(id: ID!): Post
      downvotePost(id: ID!): Post
      updatePost(
          id: ID!,
          author: String,
          title: String,
          content: String,
          url: String,
          expectedVersion: Int!
      ): Post
      addPost(
          author: String!,
          title: String!,
          content: String!,
          url: String!
      ): Post!
  }
  ```
+ Escolha **Salvar**.
+ No painel **Tipos de dados** à direita, encontre o campo **upvotePost** recém-criado no tipo **Mutação** e, em seguida, escolha **Anexar**.
+ No **menu Ação**, escolha **Atualizar runtime** e selecione **Resolvedor de unidade (somente VTL)**.
+ Em **Data source name (Nome da fonte de dados)**, escolha **PostDynamoDBTable**.
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  {
      "version" : "2017-02-28",
      "operation" : "UpdateItem",
      "key" : {
          "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
      },
      "update" : {
          "expression" : "ADD ups :plusOne, version :plusOne",
          "expressionValues" : {
              ":plusOne" : { "N" : 1 }
          }
      }
  }
  ```
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  $utils.toJson($context.result)
  ```
+ Escolha **Salvar**.
+ No painel **Tipos de dados** à direita, encontre o campo `downvotePost` recém-criado no tipo **Mutação** e, em seguida, escolha **Anexar**.
+ Em **Data source name (Nome da fonte de dados)**, escolha **PostDynamoDBTable**.
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  {
      "version" : "2017-02-28",
      "operation" : "UpdateItem",
      "key" : {
          "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
      },
      "update" : {
          "expression" : "ADD downs :plusOne, version :plusOne",
          "expressionValues" : {
              ":plusOne" : { "N" : 1 }
          }
      }
  }
  ```
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  $utils.toJson($context.result)
  ```
+ Escolha **Salvar**.

### Chamar a API para realizar voto positivo ou negativo em uma Publicação
<a name="call-the-api-to-upvote-and-downvote-a-post"></a>

Agora que os novos resolvedores foram configurados, AWS AppSync sabe como traduzir uma entrada `upvotePost` ou uma `downvote` mutação para a operação do DynamoDB. UpdateItem Agora é possível executar mutações para realizar votos positivos ou negativos na publicação criada anteriormente.
+ Escolha a guia **Consultas**.
+ No painel **Consultas**, cole a mutação a seguir. Também será necessário atualizar o argumento `id` para o valor anotado anteriormente.

  ```
  mutation votePost {
    upvotePost(id:123) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).
+ A publicação é atualizada no DynamoDB e deve aparecer no painel de resultados à direita do painel de consulta. A aparência deve ser semelhante à seguinte:

  ```
  {
    "data": {
      "upvotePost": {
        "id": "123",
        "author": "A new author",
        "title": "An empty story",
        "content": null,
        "url": "https://aws.amazon.com/appsync/",
        "ups": 6,
        "downs": 0,
        "version": 4
      }
    }
  }
  ```
+ Escolha **Executar consulta** mais algumas vezes. Você deve ver os campos `ups` e `version` incrementar em 1 a cada vez que você executar a consulta.
+ Altere a consulta para chamar a mutação `downvotePost` da seguinte forma:

  ```
  mutation votePost {
    downvotePost(id:123) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja). Dessa vez, você deve ver os campos `downs` e `version` incrementar em 1 a cada vez que você executar a consulta.

  ```
  {
    "data": {
      "downvotePost": {
        "id": "123",
        "author": "A new author",
        "title": "An empty story",
        "content": null,
        "url": "https://aws.amazon.com/appsync/",
        "ups": 6,
        "downs": 4,
        "version": 12
      }
    }
  }
  ```

## Configurando o DeletePost Resolver (DynamoDB) DeleteItem
<a name="setting-up-the-deletepost-resolver-ddb-deletepost"></a>

A próxima mutação que você quer configurar é para excluir uma publicação. Você fará isso usando a operação `DeleteItem` do DynamoDB.
+ Escolha a guia **Esquema**.
+ No painel **Esquema**, modifique o tipo `Mutation` para adicionar uma nova mutação `deletePost` da seguinte forma:

  ```
  type Mutation {
      deletePost(id: ID!, expectedVersion: Int): Post
      upvotePost(id: ID!): Post
      downvotePost(id: ID!): Post
      updatePost(
          id: ID!,
          author: String,
          title: String,
          content: String,
          url: String,
          expectedVersion: Int!
      ): Post
      addPost(
          author: String!,
          title: String!,
          content: String!,
          url: String!
      ): Post!
  }
  ```

  Dessa vez o campo `expectedVersion` é opcional, o que é explicado mais tarde ao adicionar o modelo de mapeamento da solicitação.
+ Escolha **Salvar**.
+ No painel **Tipos de dados** à direita, encontre o campo **delete** recém-criado no tipo **Mutação** e, em seguida, escolha **Anexar**.
+ No **menu Ação**, escolha **Atualizar runtime** e selecione **Resolvedor de unidade (somente VTL)**.
+ Em **Data source name (Nome da fonte de dados)**, escolha **PostDynamoDBTable**.
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  {
      "version" : "2017-02-28",
      "operation" : "DeleteItem",
      "key": {
          "id": $util.dynamodb.toDynamoDBJson($context.arguments.id)
      }
      #if( $context.arguments.containsKey("expectedVersion") )
          ,"condition" : {
              "expression"       : "attribute_not_exists(id) OR version = :expectedVersion",
              "expressionValues" : {
                  ":expectedVersion" : $util.dynamodb.toDynamoDBJson($context.arguments.expectedVersion)
              }
          }
      #end
  }
  ```

   **Observação:** o argumento `expectedVersion` é opcional. Se o chamador definir um argumento `expectedVersion` na solicitação, o modelo adiciona uma condição que permite que a solicitação `DeleteItem` seja bem-sucedida somente se o item já estiver excluído ou se o atributo `version` da publicação no DynamoDB corresponder exatamente ao `expectedVersion`. Se omitido, nenhuma expressão de condição será especificada na solicitação `DeleteItem`. Ele será bem-sucedida independentemente do valor de `version`, ou se o item existe ou não no DynamoDB.
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  $utils.toJson($context.result)
  ```

   **Observação:** mesmo que você esteja excluindo um item, é possível retornar o item que foi excluído, caso ainda não tenha sido excluído.
+ Escolha **Salvar**.

Para obter mais informações sobre mapeamento de `DeleteItem` solicitações, consulte a documentação de [DeleteItem](aws-appsync-resolver-mapping-template-reference-dynamodb-deleteitem.md)referência.

### Chamar a API para excluir uma publicação
<a name="call-the-api-to-delete-a-post"></a>

Agora, o resolvedor foi configurado e AWS AppSync sabe como traduzir uma `delete` mutação recebida em uma operação do DynamoDB. `DeleteItem` Agora você pode executar uma mutação para excluir algo na tabela.
+ Escolha a guia **Consultas**.
+ No painel **Consultas**, cole a mutação a seguir. Também será necessário atualizar o argumento `id` para o valor anotado anteriormente.

  ```
  mutation deletePost {
    deletePost(id:123) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).
+ A publicação é excluída do DynamoDB. Observe que AWS AppSync retorna o valor do item que foi excluído do DynamoDB, que deve aparecer no painel de resultados à direita do painel de consulta. A aparência deve ser semelhante à seguinte:

  ```
  {
    "data": {
      "deletePost": {
        "id": "123",
        "author": "A new author",
        "title": "An empty story",
        "content": null,
        "url": "https://aws.amazon.com/appsync/",
        "ups": 6,
        "downs": 4,
        "version": 12
      }
    }
  }
  ```

O valor é retornado somente se essa chamada para `deletePost` foi aquela que realmente a excluiu do DynamoDB.
+ Escolha **Executar consulta** novamente.
+ A chamada ainda será bem-sucedida, mas nenhum valor é retornado.

  ```
  {
    "data": {
      "deletePost": null
    }
  }
  ```

Agora vamos tentar excluir uma publicação, mas dessa vez especificando um `expectedValue`. No entanto, primeiro é necessário criar uma nova publicação, pois você acabou de excluir aquela com a qual estava trabalhando.
+ No painel **Consultas**, cole a seguinte mutação:

  ```
  mutation addPost {
    addPost(
      id:123
      author: "AUTHORNAME"
      title: "Our second post!"
      content: "A new post."
      url: "https://aws.amazon.com/appsync/"
    ) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).
+ Os resultados da publicação recém-criada devem aparecer no painel de resultados à direita do painel de consulta. Anote o `id` do objeto recém-criado, pois será necessário em alguns instantes. A aparência deve ser semelhante à seguinte:

  ```
  {
    "data": {
      "addPost": {
        "id": "123",
        "author": "AUTHORNAME",
        "title": "Our second post!",
        "content": "A new post.",
        "url": "https://aws.amazon.com/appsync/",
        "ups": 1,
        "downs": 0,
        "version": 1
      }
    }
  }
  ```

Agora vamos tentar excluir a publicação, mas coloque o valor errado para `expectedVersion`:
+ No painel **Consultas**, cole a mutação a seguir. Também será necessário atualizar o argumento `id` para o valor anotado anteriormente.

  ```
  mutation deletePost {
    deletePost(
      id:123
      expectedVersion: 9999
    ) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).

  ```
  {
    "data": {
      "deletePost": null
    },
    "errors": [
      {
        "path": [
          "deletePost"
        ],
        "data": {
          "id": "123",
          "author": "AUTHORNAME",
          "title": "Our second post!",
          "content": "A new post.",
          "url": "https://aws.amazon.com/appsync/",
          "ups": 1,
          "downs": 0,
          "version": 1
        },
        "errorType": "DynamoDB:ConditionalCheckFailedException",
        "locations": [
          {
            "line": 2,
            "column": 3
          }
        ],
        "message": "The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ)"
      }
    ]
  }
  ```

  A solicitação falhou porque a expressão de condição é avaliada como falsa: o valor para `version` da publicação no DynamoDB não corresponde ao `expectedValue` especificado nos argumentos. O valor atual do objeto é retornada no campo `data` na seção `errors` da resposta do GraphQL.
+ Repita a solicitação, mas corrija o `expectedVersion`:

  ```
  mutation deletePost {
    deletePost(
      id:123
      expectedVersion: 1
    ) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).
+ Dessa vez, a solicitação é bem-sucedida e o valor que foi excluído do DynamoDB é retornado:

  ```
  {
    "data": {
      "deletePost": {
        "id": "123",
        "author": "AUTHORNAME",
        "title": "Our second post!",
        "content": "A new post.",
        "url": "https://aws.amazon.com/appsync/",
        "ups": 1,
        "downs": 0,
        "version": 1
      }
    }
  }
  ```
+ Escolha **Executar consulta** novamente.
+ A chamada ainda é bem-sucedida, mas dessa vez nenhum valor é retornado porque a publicação já estava excluída no DynamoDB.

```
{
  "data": {
    "deletePost": null
  }
}
```

## Configurar o resolvedor allPost (Scan do DynamoDB)
<a name="setting-up-the-allpost-resolver-dynamodb-scan"></a>

Até agora, a API só será útil se você souber o `id` de cada publicação a ser examinada. Vamos adicionar um novo resolvedor que retornará todas as publicações na tabela.
+ Escolha a guia **Esquema**.
+ No painel **Esquema**, modifique o tipo `Query` para adicionar uma nova consulta `allPost` da seguinte forma:

  ```
  type Query {
      allPost(count: Int, nextToken: String): PaginatedPosts!
      getPost(id: ID): Post
  }
  ```
+ Adicione um novo tipo `PaginationPosts`:

  ```
  type PaginatedPosts {
      posts: [Post!]!
      nextToken: String
  }
  ```
+ Escolha **Salvar**.
+ No painel **Tipos de dados** à direita, encontre o campo **allPost** recém-criado no tipo **Consulta** e, em seguida, escolha **Anexar**.
+ No **menu Ação**, escolha **Atualizar runtime** e selecione **Resolvedor de unidade (somente VTL)**.
+ Em **Data source name (Nome da fonte de dados)**, escolha **PostDynamoDBTable**.
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  {
      "version" : "2017-02-28",
      "operation" : "Scan"
      #if( ${context.arguments.count} )
          ,"limit": $util.toJson($context.arguments.count)
      #end
      #if( ${context.arguments.nextToken} )
          ,"nextToken": $util.toJson($context.arguments.nextToken)
      #end
  }
  ```

  Esse resolvedor tem dois argumentos opcionais: `count`, que especifica o número máximo de itens que serão retornados em uma única chamada, e `nextToken`, que pode ser usado para recuperar o próximo conjunto de resultados, (você mostrará de onde vem o valor para `nextToken` posteriormente).
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  {
      "posts": $utils.toJson($context.result.items)
      #if( ${context.result.nextToken} )
          ,"nextToken": $util.toJson($context.result.nextToken)
      #end
  }
  ```

   **Observação:** esse modelo de mapeamento da resposta é diferente de todos os outros até agora. O resultado da consulta `allPost` é um `PaginatedPosts`, que contém uma lista de publicações e um token de paginação. A forma desse objeto é diferente da retornada do AWS AppSync DynamoDB Resolver: a lista de publicações é chamada `items` nos resultados do AWS AppSync DynamoDB Resolver, mas é chamada de entrada. `posts` `PaginatedPosts`
+ Escolha **Salvar**.

Para obter mais informações sobre o mapeamento da solicitação `Scan`, consulte a documentação de referência [Scan](aws-appsync-resolver-mapping-template-reference-dynamodb-scan.md).

### Chamar a API para verificar todas as publicações
<a name="call-the-api-to-scan-all-posts"></a>

Agora, o resolvedor foi configurado e AWS AppSync sabe como traduzir uma `allPost` consulta recebida em uma operação do DynamoDB. `Scan` Agora você pode verificar a tabela para recuperar todas as publicações.

No entanto, antes de testar, é necessário preencher a tabela com alguns dados, pois tudo que foi usado até agora já foi excluído.
+ Escolha a guia **Consultas**.
+ No painel **Consultas**, cole a seguinte mutação:

  ```
  mutation addPost {
    post1: addPost(id:1 author: "AUTHORNAME" title: "A series of posts, Volume 1" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title }
    post2: addPost(id:2 author: "AUTHORNAME" title: "A series of posts, Volume 2" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title }
    post3: addPost(id:3 author: "AUTHORNAME" title: "A series of posts, Volume 3" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title }
    post4: addPost(id:4 author: "AUTHORNAME" title: "A series of posts, Volume 4" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title }
    post5: addPost(id:5 author: "AUTHORNAME" title: "A series of posts, Volume 5" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title }
    post6: addPost(id:6 author: "AUTHORNAME" title: "A series of posts, Volume 6" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title }
    post7: addPost(id:7 author: "AUTHORNAME" title: "A series of posts, Volume 7" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title }
    post8: addPost(id:8 author: "AUTHORNAME" title: "A series of posts, Volume 8" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title }
    post9: addPost(id:9 author: "AUTHORNAME" title: "A series of posts, Volume 9" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).

Agora vamos examinar a tabela, retornando cinco resultados por vez.
+ No painel **Consultas**, cole a seguinte consulta:

  ```
  query allPost {
    allPost(count: 5) {
      posts {
        id
        title
      }
      nextToken
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).
+ As primeiras cinco publicações devem aparecer no painel de resultados à direita do painel de consulta. A aparência deve ser semelhante à seguinte:

  ```
  {
    "data": {
      "allPost": {
        "posts": [
          {
            "id": "5",
            "title": "A series of posts, Volume 5"
          },
          {
            "id": "1",
            "title": "A series of posts, Volume 1"
          },
          {
            "id": "6",
            "title": "A series of posts, Volume 6"
          },
          {
            "id": "9",
            "title": "A series of posts, Volume 9"
          },
          {
            "id": "7",
            "title": "A series of posts, Volume 7"
          }
        ],
        "nextToken": "eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGo4eHR0RG0xWXhUa1F0cEhXMEp1R3B0M1B3eThOSmRvcG9ad2RHYjI3Z0lnRkJEdXdUK09hcnovRGhNTGxLTGdMUEFBQUI1akNDQWVJR0NTcUdTSWIzRFFFSEJxQ0NBZE13Z2dIUEFnRUFNSUlCeUFZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF6ajFodkhKU1paT1pncTRaUUNBUkNBZ2dHWnJiR1dQWGxkMDB1N0xEdGY4Z2JsbktzRjRua1VCcks3TFJLcjZBTFRMeGFwVGJZMDRqOTdKVFQyYVRwSzdzbVdtNlhWWFVCTnFIOThZTzBWZHVkdDI2RlkxMHRqMDJ2QTlyNWJTUWpTbWh6NE5UclhUMG9KZWJSQ2JJbXBlaDRSVlg0Tis0WTVCN1IwNmJQWWQzOVhsbTlUTjBkZkFYMVErVCthaXZoNE5jMk50RitxVmU3SlJ5WmpzMEFkSGduM3FWd2VrOW5oeFVVd3JlK1loUks5QkRzemdiMDlmZmFPVXpzaFZ4cVJRbC93RURlOTcrRmVJdXZNby9NZ1F6dUdNbFRyalpNR3FuYzZBRnhwa0VlZTFtR0FwVDFISElUZlluakptYklmMGUzUmcxbVlnVHVSbDh4S0trNmR0QVoraEhLVDhuNUI3VnF4bHRtSnlNUXBrZGl6KzkyL3VzNDl4OWhrMnVxSW01ZFFwMjRLNnF0dm9ZK1BpdERuQTc5djhzb0grVytYT3VuQ2NVVDY4TVZ1Wk5KYkRuSEFSSEVlaTlVNVBTelU5RGZ6d2pPdmhqWDNJMWhwdWUrWi83MDVHVjlPQUxSTGlwZWZPeTFOZFhwZTdHRDZnQW00bUJUK2c1eC9Ec3ZDbWVnSDFDVXRTdHVuU1ZFa2JpZytQRC9oMUwyRTNqSHhVQldaa28yU256WUc0cG0vV1RSWkFVZHZuQT09In0="
      }
    }
  }
  ```

Você tem cinco resultados e um `nextToken` que pode ser usado para obter o próximo conjunto de resultados.
+ Atualize a consulta `allPost` para incluir o `nextToken` do conjunto de resultados anterior:

  ```
  query allPost {
    allPost(
      count: 5
      nextToken: "eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGo4eHR0RG0xWXhUa1F0cEhXMEp1R3B0M1B3eThOSmRvcG9ad2RHYjI3Z0lnRlluNktJRWl6V0ZlR3hJOVJkaStrZUFBQUI1akNDQWVJR0NTcUdTSWIzRFFFSEJxQ0NBZE13Z2dIUEFnRUFNSUlCeUFZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF5cW8yUGFSZThnalFpemRCTUNBUkNBZ2dHWk1JODhUNzhIOFVUZGtpdFM2ZFluSWRyVDg4c2lkN1RjZzB2d1k3VGJTTWpSQ2U3WjY3TkUvU2I1dWNETUdDMmdmMHErSGJSL0pteGRzYzVEYnE1K3BmWEtBdU5jSENJdWNIUkJ0UHBPWVdWdCtsS2U5L1pNcWdocXhrem1RaXI1YnIvQkt6dU5hZmJCdE93NmtoM2Jna1BKM0RjWWhpMFBGbmhMVGg4TUVGSjBCcXg3RTlHR1V5N0tUS0JLZlV3RjFQZ0JRREdrNzFYQnFMK2R1S2IrVGtZZzVYMjFrc3NyQmFVTmNXZmhTeXE0ZUJHSWhqZWQ5c3VKWjBSSTc2ZnVQdlZkR3FLNENjQmxHYXhpekZnK2pKK1FneEU1SXduRTNYYU5TR0I4QUpmamR2bU1wbUk1SEdvWjlMUUswclczbG14RDRtMlBsaTNLaEVlcm9pem5zcmdINFpvcXIrN2ltRDN3QkJNd3BLbGQzNjV5Nnc4ZnMrK2FnbTFVOUlKOFFrOGd2bEgySHFROHZrZXBrMWlLdWRIQ25LaS9USnBlMk9JeEVPazVnRFlzRTRUU09HUlVJTkxYY2MvdW1WVEpBMUthV2hWTlAvdjNlSnlZQUszbWV6N2h5WHVXZ1BkTVBNWERQdTdjVnVRa3EwK3NhbGZOd2wvSUx4bHNyNDVwTEhuVFpyRWZvVlV1bXZ5S2VKY1RUU1lET05hM1NwWEd2UT09In0="
    ) {
      posts {
        id
        author
      }
      nextToken
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).
+ As quatro publicações restantes devem aparecer no painel de resultados à direita do painel de consulta. Não há `nextToken` nesse conjunto de resultados pois todos os nove resultados foram encontrados, sem nenhum restante. A aparência deve ser semelhante à seguinte:

  ```
  {
    "data": {
      "allPost": {
        "posts": [
          {
            "id": "2",
            "title": "A series of posts, Volume 2"
          },
          {
            "id": "3",
            "title": "A series of posts, Volume 3"
          },
          {
            "id": "4",
            "title": "A series of posts, Volume 4"
          },
          {
            "id": "8",
            "title": "A series of posts, Volume 8"
          }
        ],
        "nextToken": null
      }
    }
  }
  ```

## Configurando o allPostsBy Author Resolver (DynamoDB Query)
<a name="setting-up-the-allpostsbyauthor-resolver-ddb-query"></a>

Além de verificar todas as publicações do DynamoDB, também é possível consultar o DynamoDB para recuperar as publicações criadas por um determinado autor. A tabela do DynamoDB criada anteriormente já possui um `GlobalSecondaryIndex` chamado `author-index` que podemos usar com uma operação `Query` do DynamoDB para recuperar todos as publicações criadas por um determinado autor.
+ Escolha a guia **Esquema**.
+ No painel **Esquema**, modifique o tipo `Query` para adicionar uma nova consulta `allPostsByAuthor` da seguinte forma:

  ```
  type Query {
      allPostsByAuthor(author: String!, count: Int, nextToken: String): PaginatedPosts!
      allPost(count: Int, nextToken: String): PaginatedPosts!
      getPost(id: ID): Post
  }
  ```

   **Observação:** isso usa o mesmo tipo `PaginatedPosts` usado com a consulta `allPost`.
+ Escolha **Salvar**.
+ No painel **Tipos de dados** à direita, localize o campo **allPostsByAutor** recém-criado no Tipo de **consulta** e escolha **Anexar**.
+ No **menu Ação**, escolha **Atualizar runtime** e selecione **Resolvedor de unidade (somente VTL)**.
+ Em **Data source name (Nome da fonte de dados)**, escolha **PostDynamoDBTable**.
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  {
      "version" : "2017-02-28",
      "operation" : "Query",
      "index" : "author-index",
      "query" : {
        "expression": "author = :author",
          "expressionValues" : {
            ":author" : $util.dynamodb.toDynamoDBJson($context.arguments.author)
          }
      }
      #if( ${context.arguments.count} )
          ,"limit": $util.toJson($context.arguments.count)
      #end
      #if( ${context.arguments.nextToken} )
          ,"nextToken": "${context.arguments.nextToken}"
      #end
  }
  ```

  Como o resolvedor `allPost`, esse resolvedor tem dois argumentos opcionais: `count`, que especifica o número máximo de itens que serão retornados em uma única chamada e `nextToken`, que pode ser usado para recuperar o próximo conjunto de resultados (o valor para `nextToken` pode ser obtido de uma chamada anterior).
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  {
      "posts": $utils.toJson($context.result.items)
      #if( ${context.result.nextToken} )
          ,"nextToken": $util.toJson($context.result.nextToken)
      #end
  }
  ```

   **Observação:** esse é o mesmo modelo de mapeamento da resposta usado no resolvedor `allPost`.
+ Escolha **Salvar**.

Para obter mais informações sobre o mapeamento da solicitação `Query`, consulte a documentação de referência [Consulta](aws-appsync-resolver-mapping-template-reference-dynamodb-query.md).

### Chamar a API para consultar todas as publicações de um autor
<a name="call-the-api-to-query-all-posts-by-an-author"></a>

Agora, o resolvedor foi configurado e AWS AppSync sabe como traduzir uma `allPostsByAuthor` mutação recebida em uma operação do DynamoDB em relação ao índice`Query`. `author-index` Agora você pode consultar a tabela para recuperar todas as publicações de um determinado autor.

Antes de fazer isso, no entanto, vamos preencher a tabela com mais algumas publicações pois até agora todas têm o mesmo autor.
+ Escolha a guia **Consultas**.
+ No painel **Consultas**, cole a seguinte mutação:

  ```
  mutation addPost {
    post1: addPost(id:10 author: "Nadia" title: "The cutest dog in the world" content: "So cute. So very, very cute." url: "https://aws.amazon.com/appsync/" ) { author, title }
    post2: addPost(id:11 author: "Nadia" title: "Did you know...?" content: "AppSync works offline?" url: "https://aws.amazon.com/appsync/" ) { author, title }
    post3: addPost(id:12 author: "Steve" title: "I like GraphQL" content: "It's great" url: "https://aws.amazon.com/appsync/" ) { author, title }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).

Agora, vamos consultar a tabela, retornando todas as publicações de autoria da `Nadia`.
+ No painel **Consultas**, cole a seguinte consulta:

  ```
  query allPostsByAuthor {
    allPostsByAuthor(author: "Nadia") {
      posts {
        id
        title
      }
      nextToken
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).
+ Todas as publicações de autoria da `Nadia` devem aparecer no painel de resultados à direita do painel de consulta. A aparência deve ser semelhante à seguinte:

  ```
  {
    "data": {
      "allPostsByAuthor": {
        "posts": [
          {
            "id": "10",
            "title": "The cutest dog in the world"
          },
          {
            "id": "11",
            "title": "Did you know...?"
          }
        ],
        "nextToken": null
      }
    }
  }
  ```

A paginação funciona para `Query` da mesma forma que funciona para `Scan`. Por exemplo, vamos procurar todas as publicações por `AUTHORNAME`, obtendo cinco por vez.
+ No painel **Consultas**, cole a seguinte consulta:

  ```
  query allPostsByAuthor {
    allPostsByAuthor(
      author: "AUTHORNAME"
      count: 5
    ) {
      posts {
        id
        title
      }
      nextToken
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).
+ Todas as publicações de autoria da `AUTHORNAME` devem aparecer no painel de resultados à direita do painel de consulta. A aparência deve ser semelhante à seguinte:

  ```
  {
    "data": {
      "allPostsByAuthor": {
        "posts": [
          {
            "id": "6",
            "title": "A series of posts, Volume 6"
          },
          {
            "id": "4",
            "title": "A series of posts, Volume 4"
          },
          {
            "id": "2",
            "title": "A series of posts, Volume 2"
          },
          {
            "id": "7",
            "title": "A series of posts, Volume 7"
          },
          {
            "id": "1",
            "title": "A series of posts, Volume 1"
          }
        ],
        "nextToken": "eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGo4eHR0RG0xWXhUa1F0cEhXMEp1R3B0M1B3eThOSmRvcG9ad2RHYjI3Z0lnSExqRnVhVUR3ZUhEZ2QzNGJ2QlFuY0FBQUNqekNDQW9zR0NTcUdTSWIzRFFFSEJxQ0NBbnd3Z2dKNEFnRUFNSUlDY1FZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF5Qkg4Yk1obW9LVEFTZHM3SUNBUkNBZ2dKQ3dISzZKNlJuN3pyYUVKY1pWNWxhSkNtZW1KZ0F5N1dhZkc2UEdTNHpNQzJycTkwZHFJTFV6Z25wck9Gd3pMS3VOQ2JvUXc3VDI5eCtnVExIbGg4S3BqbzB1YjZHQ3FwcDhvNDVmMG9JbDlmdS9JdjNXcFNNSXFKTXZ1MEVGVWs1VzJQaW5jZGlUaVRtZFdYWlU1bkV2NkgyRFBRQWZYYlNnSmlHSHFLbmJZTUZZM0FTdmRIL0hQaVZBb1RCMk1YZkg0eGJOVTdEbjZtRFNhb2QwbzdHZHJEWDNtODQ1UXBQUVNyUFhHemY0WDkyajhIdlBCSWE4Smcrb0RxbHozUVQ5N2FXUXdYWWU2S0h4emI1ejRITXdEdXEyRDRkYzhoMi9CbW10MzRMelVGUVIyaExSZGRaZ0xkdzF5cHJZdFZwY3dEc1d4UURBTzdOcjV2ZEp4VVR2TVhmODBRSnp1REhXREpTVlJLdDJwWmlpaXhXeGRwRmNod1BzQ3d2aVBqMGwrcWFFWU1jMXNQbENkVkFGem43VXJrSThWbS8wWHlwR2xZb3BSL2FkV0xVekgrbGMrYno1ZEM2SnVLVXdtY1EyRXlZeDZiS0Izbi9YdUViWGdFeU5PMWZTdE1rRlhyWmpvMVpzdlYyUFRjMzMrdEs0ZDhkNkZrdjh5VVR6WHhJRkxIaVNsOUx6VVdtT3BCaWhrTFBCT09jcXkyOHh1UmkzOEM3UFRqMmN6c3RkOUo1VUY0azBJdUdEbVZzM2xjdWg1SEJjYThIeXM2aEpvOG1HbFpMNWN6R2s5bi8vRE1EbDY3RlJraG5QNFNhSDBpZGI5VFEvMERLeFRBTUdhcWpPaEl5ekVqd2ZDQVJleFdlbldyOGlPVkhScDhGM25WZVdvbFRGK002N0xpdi9XNGJXdDk0VEg3b0laUU5lYmZYKzVOKy9Td25Hb1dyMTlWK0pEb2lIRVFLZ1cwMWVuYjZKUXo5Slh2Tm95ZzF3RnJPVmxGc2xwNlRHa1BlN2Rnd2IrWT0ifQ=="
      }
    }
  }
  ```
+ Atualize o argumento `nextToken` com o valor retornado pela consulta anterior da seguinte forma:

  ```
  query allPostsByAuthor {
    allPostsByAuthor(
      author: "AUTHORNAME"
      count: 5
      nextToken: "eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGo4eHR0RG0xWXhUa1F0cEhXMEp1R3B0M1B3eThOSmRvcG9ad2RHYjI3Z0lnSExqRnVhVUR3ZUhEZ2QzNGJ2QlFuY0FBQUNqekNDQW9zR0NTcUdTSWIzRFFFSEJxQ0NBbnd3Z2dKNEFnRUFNSUlDY1FZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF5Qkg4Yk1obW9LVEFTZHM3SUNBUkNBZ2dKQ3dISzZKNlJuN3pyYUVKY1pWNWxhSkNtZW1KZ0F5N1dhZkc2UEdTNHpNQzJycTkwZHFJTFV6Z25wck9Gd3pMS3VOQ2JvUXc3VDI5eCtnVExIbGg4S3BqbzB1YjZHQ3FwcDhvNDVmMG9JbDlmdS9JdjNXcFNNSXFKTXZ1MEVGVWs1VzJQaW5jZGlUaVRtZFdYWlU1bkV2NkgyRFBRQWZYYlNnSmlHSHFLbmJZTUZZM0FTdmRIL0hQaVZBb1RCMk1YZkg0eGJOVTdEbjZtRFNhb2QwbzdHZHJEWDNtODQ1UXBQUVNyUFhHemY0WDkyajhIdlBCSWE4Smcrb0RxbHozUVQ5N2FXUXdYWWU2S0h4emI1ejRITXdEdXEyRDRkYzhoMi9CbW10MzRMelVGUVIyaExSZGRaZ0xkdzF5cHJZdFZwY3dEc1d4UURBTzdOcjV2ZEp4VVR2TVhmODBRSnp1REhXREpTVlJLdDJwWmlpaXhXeGRwRmNod1BzQ3d2aVBqMGwrcWFFWU1jMXNQbENkVkFGem43VXJrSThWbS8wWHlwR2xZb3BSL2FkV0xVekgrbGMrYno1ZEM2SnVLVXdtY1EyRXlZeDZiS0Izbi9YdUViWGdFeU5PMWZTdE1rRlhyWmpvMVpzdlYyUFRjMzMrdEs0ZDhkNkZrdjh5VVR6WHhJRkxIaVNsOUx6VVdtT3BCaWhrTFBCT09jcXkyOHh1UmkzOEM3UFRqMmN6c3RkOUo1VUY0azBJdUdEbVZzM2xjdWg1SEJjYThIeXM2aEpvOG1HbFpMNWN6R2s5bi8vRE1EbDY3RlJraG5QNFNhSDBpZGI5VFEvMERLeFRBTUdhcWpPaEl5ekVqd2ZDQVJleFdlbldyOGlPVkhScDhGM25WZVdvbFRGK002N0xpdi9XNGJXdDk0VEg3b0laUU5lYmZYKzVOKy9Td25Hb1dyMTlWK0pEb2lIRVFLZ1cwMWVuYjZKUXo5Slh2Tm95ZzF3RnJPVmxGc2xwNlRHa1BlN2Rnd2IrWT0ifQ=="
    ) {
      posts {
        id
        title
      }
      nextToken
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).
+ As publicações restantes de autoria de `AUTHORNAME` devem aparecer no painel de resultados à direita do painel de consulta. A aparência deve ser semelhante à seguinte:

  ```
  {
    "data": {
      "allPostsByAuthor": {
        "posts": [
          {
            "id": "8",
            "title": "A series of posts, Volume 8"
          },
          {
            "id": "5",
            "title": "A series of posts, Volume 5"
          },
          {
            "id": "3",
            "title": "A series of posts, Volume 3"
          },
          {
            "id": "9",
            "title": "A series of posts, Volume 9"
          }
        ],
        "nextToken": null
      }
    }
  }
  ```

## Uso de conjuntos
<a name="using-sets"></a>

Até esse ponto, o `Post` tipo era um key/value objeto plano. Você também pode modelar objetos complexos com o resolvedor de AWS AppSyncDynamo banco de dados, como conjuntos, listas e mapas.

Vamos atualizar o tipo `Post` para incluir tags. Uma publicação pode ter 0 ou mais tags, que são armazenadas no DynamoDB como um Conjunto de strings. Vamos configurar também algumas mutações para adicionar e remover tags, e uma nova consulta para verificar as publicações com uma tag específica.
+ Escolha a guia **Esquema**.
+ No painel **Esquema**, modifique o tipo `Post` para adicionar um novo campo `tags` da seguinte forma:

  ```
  type Post {
    id: ID!
    author: String
    title: String
    content: String
    url: String
    ups: Int!
    downs: Int!
    version: Int!
    tags: [String!]
  }
  ```
+ No painel **Esquema**, modifique o tipo `Query` para adicionar uma nova consulta `allPostsByTag` da seguinte forma:

  ```
  type Query {
    allPostsByTag(tag: String!, count: Int, nextToken: String): PaginatedPosts!
    allPostsByAuthor(author: String!, count: Int, nextToken: String): PaginatedPosts!
    allPost(count: Int, nextToken: String): PaginatedPosts!
    getPost(id: ID): Post
  }
  ```
+ No painel **Esquema**, modifique o tipo `Mutation` para adicionar novas mutações `addTag` e `removeTag` da seguinte forma:

  ```
  type Mutation {
    addTag(id: ID!, tag: String!): Post
    removeTag(id: ID!, tag: String!): Post
    deletePost(id: ID!, expectedVersion: Int): Post
    upvotePost(id: ID!): Post
    downvotePost(id: ID!): Post
    updatePost(
      id: ID!,
      author: String,
      title: String,
      content: String,
      url: String,
      expectedVersion: Int!
    ): Post
    addPost(
      author: String!,
      title: String!,
      content: String!,
      url: String!
    ): Post!
  }
  ```
+ Escolha **Salvar**.
+ No painel **Tipos de dados** à direita, localize o campo **allPostsByTag** recém-criado no Tipo de **consulta** e escolha **Anexar**.
+ Em **Data source name (Nome da fonte de dados)**, escolha **PostDynamoDBTable**.
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  {
      "version" : "2017-02-28",
      "operation" : "Scan",
      "filter": {
        "expression": "contains (tags, :tag)",
          "expressionValues": {
            ":tag": $util.dynamodb.toDynamoDBJson($context.arguments.tag)
          }
      }
      #if( ${context.arguments.count} )
          ,"limit": $util.toJson($context.arguments.count)
      #end
      #if( ${context.arguments.nextToken} )
          ,"nextToken": $util.toJson($context.arguments.nextToken)
      #end
  }
  ```
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  {
      "posts": $utils.toJson($context.result.items)
      #if( ${context.result.nextToken} )
          ,"nextToken": $util.toJson($context.result.nextToken)
      #end
  }
  ```
+ Escolha **Salvar**.
+ No painel **Tipos de dados** à direita, encontre o campo **addTag** recém-criado no tipo **Mutação** e, em seguida, escolha **Anexar**.
+ Em **Data source name (Nome da fonte de dados)**, escolha **PostDynamoDBTable**.
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  {
      "version" : "2017-02-28",
      "operation" : "UpdateItem",
      "key" : {
          "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
      },
      "update" : {
          "expression" : "ADD tags :tags, version :plusOne",
          "expressionValues" : {
              ":tags" : { "SS": [ $util.toJson($context.arguments.tag) ] },
              ":plusOne" : { "N" : 1 }
          }
      }
  }
  ```
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  $utils.toJson($context.result)
  ```
+ Escolha **Salvar**.
+ No painel **Tipos de dados** à direita, encontre o campo **removeTag** recém-criado no tipo **Mutação** e, em seguida, escolha **Anexar**.
+ Em **Data source name (Nome da fonte de dados)**, escolha **PostDynamoDBTable**.
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  {
      "version" : "2017-02-28",
      "operation" : "UpdateItem",
      "key" : {
          "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
      },
      "update" : {
          "expression" : "DELETE tags :tags ADD version :plusOne",
          "expressionValues" : {
              ":tags" : { "SS": [ $util.toJson($context.arguments.tag) ] },
              ":plusOne" : { "N" : 1 }
          }
      }
  }
  ```
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  $utils.toJson($context.result)
  ```
+ Escolha **Salvar**.

### Chamar a API para trabalhar com tags
<a name="call-the-api-to-work-with-tags"></a>

Agora que você configurou os resolvedores, AWS AppSync sabe como traduzir as entradas `addTag` e as `allPostsByTag` solicitações em DynamoDB e operações. `removeTag` `UpdateItem` `Scan`

Para testar, vamos selecionar uma das publicações criadas anteriormente. Por exemplo, vamos usar uma publicação de autoria da `Nadia`.
+ Escolha a guia **Consultas**.
+ No painel **Consultas**, cole a seguinte consulta:

  ```
  query allPostsByAuthor {
    allPostsByAuthor(
      author: "Nadia"
    ) {
      posts {
        id
        title
      }
      nextToken
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).
+ Todas as publicações da Nadia devem aparecer no painel de resultados à direita do painel de consulta. A aparência deve ser semelhante à seguinte:

  ```
  {
    "data": {
      "allPostsByAuthor": {
        "posts": [
          {
            "id": "10",
            "title": "The cutest dog in the world"
          },
          {
            "id": "11",
            "title": "Did you known...?"
          }
        ],
        "nextToken": null
      }
    }
  }
  ```
+ Vamos usar aquela com o título `"The cutest dog in the world"`. Anote seu `id` pois ele será usado posteriormente.

Agora vamos tentar adicionar uma tag `dog`.
+ No painel **Consultas**, cole a mutação a seguir. Também será necessário atualizar o argumento `id` para o valor anotado anteriormente.

  ```
  mutation addTag {
    addTag(id:10 tag: "dog") {
      id
      title
      tags
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).
+ A publicação é atualizada com a nova tag.

  ```
  {
    "data": {
      "addTag": {
        "id": "10",
        "title": "The cutest dog in the world",
        "tags": [
          "dog"
        ]
      }
    }
  }
  ```

Adicione uma ou mais tags da seguinte forma:
+ Atualize a mutação para alterar o argumento `tag` para `puppy`.

  ```
  mutation addTag {
    addTag(id:10 tag: "puppy") {
      id
      title
      tags
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).
+ A publicação é atualizada com a nova tag.

  ```
  {
    "data": {
      "addTag": {
        "id": "10",
        "title": "The cutest dog in the world",
        "tags": [
          "dog",
          "puppy"
        ]
      }
    }
  }
  ```

Também é possível excluir tags:
+ No painel **Consultas**, cole a mutação a seguir. Também será necessário atualizar o argumento `id` para o valor anotado anteriormente.

  ```
  mutation removeTag {
    removeTag(id:10 tag: "puppy") {
      id
      title
      tags
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).
+ A publicação é atualizada e a tag `puppy` é excluída.

  ```
  {
    "data": {
      "addTag": {
        "id": "10",
        "title": "The cutest dog in the world",
        "tags": [
          "dog"
        ]
      }
    }
  }
  ```

Também é possível pesquisar todas as publicações com uma tag:
+ No painel **Consultas**, cole a seguinte consulta:

  ```
  query allPostsByTag {
    allPostsByTag(tag: "dog") {
      posts {
        id
        title
        tags
      }
      nextToken
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).
+ Todos as publicações com a tag `dog` são retornadas da seguinte forma:

  ```
  {
    "data": {
      "allPostsByTag": {
        "posts": [
          {
            "id": "10",
            "title": "The cutest dog in the world",
            "tags": [
              "dog",
              "puppy"
            ]
          }
        ],
        "nextToken": null
      }
    }
  }
  ```

## Uso de listas e mapas
<a name="using-lists-and-maps"></a>

Além de usar conjuntos do DynamoDB, também é possível usar listas e mapas do DynamoDB para modelar dados complexos em um único objeto.

Vamos adicionar a capacidade de adicionar comentários em publicações. Isso será modelado como uma lista de objetos de mapa no objeto `Post` no DynamoDB.

 **Observação:** em um aplicativo real, os comentários seriam modelados em suas próprias tabelas. Para este tutorial, basta adicioná-los à tabela `Post`.
+ Escolha a guia **Esquema**.
+ No painel **Esquema**, adicione um novo tipo `Comment` da seguinte forma:

  ```
  type Comment {
      author: String!
      comment: String!
  }
  ```
+ No painel **Esquema**, modifique o tipo `Post` para adicionar um novo campo `comments` da seguinte forma:

  ```
  type Post {
    id: ID!
    author: String
    title: String
    content: String
    url: String
    ups: Int!
    downs: Int!
    version: Int!
    tags: [String!]
    comments: [Comment!]
  }
  ```
+ No painel **Esquema**, modifique o tipo `Mutation` para adicionar uma nova mutação `addComment` da seguinte forma:

  ```
  type Mutation {
    addComment(id: ID!, author: String!, comment: String!): Post
    addTag(id: ID!, tag: String!): Post
    removeTag(id: ID!, tag: String!): Post
    deletePost(id: ID!, expectedVersion: Int): Post
    upvotePost(id: ID!): Post
    downvotePost(id: ID!): Post
    updatePost(
      id: ID!,
      author: String,
      title: String,
      content: String,
      url: String,
      expectedVersion: Int!
    ): Post
    addPost(
      author: String!,
      title: String!,
      content: String!,
      url: String!
    ): Post!
  }
  ```
+ Escolha **Salvar**.
+ No painel **Tipos de dados** à direita, encontre o campo **addComment** recém-criado no tipo **Mutação** e, em seguida, escolha **Anexar**.
+ Em **Data source name (Nome da fonte de dados)**, escolha **PostDynamoDBTable**.
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  {
    "version" : "2017-02-28",
    "operation" : "UpdateItem",
    "key" : {
      "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
    },
    "update" : {
      "expression" : "SET comments = list_append(if_not_exists(comments, :emptyList), :newComment) ADD version :plusOne",
      "expressionValues" : {
        ":emptyList": { "L" : [] },
        ":newComment" : { "L" : [
          { "M": {
            "author": $util.dynamodb.toDynamoDBJson($context.arguments.author),
            "comment": $util.dynamodb.toDynamoDBJson($context.arguments.comment)
            }
          }
        ] },
        ":plusOne" : $util.dynamodb.toDynamoDBJson(1)
      }
    }
  }
  ```

  Essa expressão de atualização anexará uma lista que contém o novo comentário à lista `comments` existente. Se a lista ainda não existir, ela será criada.
+ Em **Configurar o modelo de mapeamento da solicitação**, cole o seguinte:

  ```
  $utils.toJson($context.result)
  ```
+ Escolha **Salvar**.

### Chamar a API para adicionar um comentário
<a name="call-the-api-to-add-a-comment"></a>

Agora que você configurou os resolvedores, AWS AppSync sabe como traduzir as `addComment` solicitações recebidas em operações do DynamoDB. `UpdateItem`

Vamos testar adicionando um comentário à mesma publicação na qual as tags foram adicionadas.
+ Escolha a guia **Consultas**.
+ No painel **Consultas**, cole a seguinte consulta:

  ```
  mutation addComment {
    addComment(
      id:10
      author: "Steve"
      comment: "Such a cute dog."
    ) {
      id
      comments {
        author
        comment
      }
    }
  }
  ```
+ Escolha **Executar consulta** (o botão de reprodução laranja).
+ Todas as publicações da Nadia devem aparecer no painel de resultados à direita do painel de consulta. A aparência deve ser semelhante à seguinte:

  ```
  {
    "data": {
      "addComment": {
        "id": "10",
        "comments": [
          {
            "author": "Steve",
            "comment": "Such a cute dog."
          }
        ]
      }
    }
  }
  ```

Se você executar a solicitação várias vezes, vários comentários serão anexados à lista.

## Conclusão
<a name="conclusion"></a>

Neste tutorial, você criou uma API que nos permite manipular objetos Post no DynamoDB usando o GraphQL. AWS AppSync Para obter mais informações, consulte a [Referência do modelo de mapeamento do resolvedor](resolver-mapping-template-reference.md#aws-appsync-resolver-mapping-template-reference).

Para limpar, você pode excluir a API AppSync GraphQL do console.

Para excluir a tabela do DynamoDB e a função do IAM que você criou para este tutorial, você pode executar o seguinte para excluir a pilha ou visitar `AWSAppSyncTutorialForAmazonDynamoDB` o console e excluir CloudFormation a pilha:

```
aws cloudformation delete-stack \
    --stack-name AWSAppSyncTutorialForAmazonDynamoDB
```