

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

# Projetando o GraphQL APIs com AWS AppSync
<a name="designing-a-graphql-api"></a>

AWS AppSync permite que você crie o GraphQL APIs usando a experiência do console. Abordamos isso rapidamente na seção [Lançar um esquema de amostra](https://docs.aws.amazon.com/appsync/latest/devguide/quickstart.html). No entanto, esse guia não mostrou todo o catálogo de opções e configurações que você poderia aproveitar. AWS AppSync

Quando você escolhe criar uma API GraphQL no console, há várias opções a serem exploradas. Se você seguiu as orientações do guia [Launching a sample schema](https://docs.aws.amazon.com/appsync/latest/devguide/quickstart.html), mostramos como criar uma API usando um modelo predefinido. Nas seções a seguir, guiaremos você pelo restante das opções e configurações para criar o APIs AWS AppSync GraphQL no.

Nesta seção, você analisa os seguintes conceitos:

1. [Blank APIs or imports](blank-import-api.md#aws-appsync-blank-import-api): este guia aborda todo o processo de criação de uma API GraphQL. Você vai aprender a criar uma API GraphQL a partir de um modelo em branco sem modelo, configurar fontes de dados para seu esquema e adicionar seu primeiro resolvedor a um campo.

1. [Real-time data](aws-appsync-real-time-data.md#aws-appsync-real-time-data-anchor): este guia mostrará as possíveis opções para criar uma API usando AWS AppSync o WebSocket mecanismo.

1. [Merged APIs](merged-api.md#aws-appsync-merged-api): Este guia mostrará como criar um novo GraphQL APIs associando e mesclando dados de vários GraphQL existentes. APIs

1. [Construindo o GraphQL APIs com introspecção do RDS](rds-introspection.md): este guia mostrará como integrar as tabelas do Amazon RDS usando uma API de dados.

# Estruturação de uma API GraphQL (em branco ou importada) APIs
<a name="blank-import-api"></a>

Antes de criar sua API GraphQL a partir de um modelo em branco, leia os conceitos sobre o GraphQL. Há três componentes fundamentais de uma API GraphQL:

1. O **esquema** é o arquivo que contém a forma e a definição dos seus dados. Quando uma solicitação é feita por um cliente ao seu serviço do GraphQL, os dados retornados seguem a especificação do esquema. Para obter mais informações, consulte [Esquemas do GraphQL](schema-components.md#aws-appsync-schema-components).

1. A **fonte de dados** é anexada ao seu esquema. Quando uma solicitação é feita, os dados são recuperados e modificados. Para obter mais informações, consulte [Fontes de dados](data-source-components.md#aws-appsync-data-source-components).

1. O **resolvedor** fica entre o esquema e a fonte de dados. Quando uma solicitação é feita, o resolvedor executa a operação nos dados da fonte e retorna o resultado como resposta. Para obter mais informações, consulte [Resolvedores](resolver-components.md#aws-appsync-resolver-components).

![\[GraphQL API architecture showing schema, resolvers, and data sources connected via AppSync.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/appsync-architecture-graphql-api.png)


AWS AppSync gerencia você, APIs permitindo que você crie, edite e armazene o código para seus esquemas e resolvedores. Suas fontes de dados serão provenientes de repositórios externos, como bancos de dados, tabelas do DynamoDB e funções do Lambda. Se você estiver usando um AWS serviço para armazenar seus dados ou estiver planejando fazer isso, AWS AppSync oferece uma experiência quase perfeita ao associar dados de suas contas AWS ao seu GraphQL. APIs

Na próxima seção, você aprenderá a criar cada um desses componentes usando o AWS AppSync serviço.

**Topics**
+ [Como projetar seu esquema GraphQL](designing-your-schema.md)
+ [Como anexar uma fonte de dados](attaching-a-data-source.md)
+ [Configuração de resolvedores do AWS AppSync](resolver-config-overview.md)
+ [Usando APIs com o CDK](using-your-api.md)

# Como projetar seu esquema GraphQL
<a name="designing-your-schema"></a>

O esquema GraphQL é a base de qualquer implementação de servidor de GraphQL. Cada API GraphQL é definida por um **único** esquema que contém tipos e campos que descrevem como os dados das solicitações serão preenchidos. Os dados que fluem pela sua API e as operações realizadas devem ser validados com base no esquema.

O [sistema do tipo GraphQL](https://graphql.org/learn/schema/#type-system) descreve os recursos de um servidor de GraphQL e é usado para determinar se uma consulta é válida. Um sistema de tipo de servidor geralmente é chamado de esquema e pode consistir em diferentes tipos de objetos, escalares, entradas, entre outros. O GraphQL é declarativo e fortemente tipificado, o que significa que os tipos serão bem definidos no runtime e retornarão somente o que foi especificado.

AWS AppSync permite que você defina e configure esquemas do GraphQL. A seção a seguir descreve como criar esquemas do GraphQL do zero usando AWS AppSync os serviços da.

## Estruturar um esquema do GraphQL
<a name="schema-structure"></a>

**dica**  
Consulte a seção [Schemas](https://docs.aws.amazon.com//appsync/latest/devguide/schema-components.html) antes de continuar.

O GraphQL é uma ferramenta poderosa para implementar serviços de API. A descrição (em tradução livre) no [site do GraphQL](https://graphql.org/) é a seguinte:

“O *GraphQL é uma linguagem de consulta APIs e um tempo de execução para atender essas consultas com seus dados existentes. O GraphQL fornece uma descrição completa e compreensível dos dados em sua API, dá aos clientes o poder de pedir exatamente o que precisam e nada mais, facilita a evolução ao APIs longo do tempo e habilita ferramentas poderosas para desenvolvedores.* “

Esta seção aborda a primeira parte da sua implementação do GraphQL, o esquema. De acordo com a citação acima, um esquema “fornece uma descrição completa e clara dos dados em sua API”. Em outras palavras, um esquema do GraphQL é uma representação textual dos dados, das operações e das relações entre eles referentes ao seu serviço. O esquema é considerado o principal ponto de entrada para a implementação do serviço do GraphQL. Não é de surpreender que muitas vezes seja uma das primeiras coisas que você faz em seu projeto. Consulte a seção [Schemas](https://docs.aws.amazon.com//appsync/latest/devguide/schema-components.html) antes de continuar.

Citando a seção [Schemas](https://docs.aws.amazon.com//appsync/latest/devguide/schema-components.html), os esquemas do GraphQL são escritos em *Schema Definition Language* (SDL). O SDL é composto por tipos e campos com uma estrutura estabelecida:
+ **Tipos**: os tipos são como o GraphQL define a forma e o comportamento dos dados. O GraphQL é compatível com uma infinidade de tipos que serão explicados ainda nesta seção. Cada um dos tipos definidos em seu esquema terá um escopo próprio. Dentro do escopo, um ou mais campos vão apresentar um valor ou lógica que será usada em seu serviço do GraphQL. Os tipos têm muitas funções diferentes, sendo as mais comuns objetos ou escalares (tipos de valores primitivos).
+ **Campos**: os campos existem dentro do escopo de um tipo e contêm o valor solicitado do serviço do GraphQL. Eles são muito semelhantes às variáveis de outras linguagens de programação. A forma dos dados que você define em seus campos determinará como os dados são estruturados em uma request/response operação. Isso permite que os desenvolvedores prevejam o que será retornado sem saber como o back-end do serviço é implementado.

Os esquemas mais simples conterão três categorias de dados:

1. **Raízes do esquema**: as raízes definem os pontos de entrada do seu esquema. Elas apontam para os campos que realizarão alguma operação nos dados, como adicionar, excluir ou modificar algo.

1. **Tipos**: esses são tipos básicos usados para representar o formato dos dados. Eles são muito semelhantes a objetos ou representações abstratas de algo com características definidas. Por exemplo, você pode criar um objeto `Person` que represente uma pessoa em um banco de dados. As características de cada pessoa serão definidas dentro de `Person` como campos. Eles podem ser qualquer dado da pessoa, como o nome, a idade, o emprego, o endereço etc.

1. **Tipos de objetos especiais**: esses são os tipos que definem o comportamento das operações em seu esquema. Cada tipo de objeto especial é definido uma vez por esquema. Eles são colocados primeiro na raiz do esquema e, em seguida, definidos no corpo do esquema. Cada campo em um tipo de objeto especial define uma única operação a ser implementada pelo seu solucionador.

Para entender melhor, imagine que você esteja criando um serviço que armazena dados de autores de livros e suas obras. Cada autor tem um nome e uma série de livros escritos. Cada livro tem um nome e uma lista de autores associados. Além disso, queremos adicionar ou recuperar livros e autores. Uma representação UML simples desse relacionamento pode ser como esta:

![\[UML diagram showing Author and Book classes with attributes and methods, linked by association.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/GraphQL-UML-1.png)


No GraphQL, as entidades `Author` e `Book` representam dois tipos diferentes de objetos em seu esquema:

```
type Author {
}

type Book {
}
```

`Author` contém `authorName` e `Books`, enquanto `Book` contém `bookName` e `Authors`. Eles podem ser representados como os campos dentro do escopo de seus tipos:

```
type Author {
  authorName: String
  Books: [Book]
}

type Book {
  bookName: String
  Authors: [Author]
}
```

Como você pode ver, as representações de tipo estão muito próximas do diagrama. No entanto, os métodos são os pontos mais complexos. Eles serão colocados em um dos poucos tipos de objetos especiais como um campo. A categorização como objeto especial depende do comportamento dele. O GraphQL contém três tipos fundamentais de objetos especiais: consultas, mutações e assinaturas. Para obter mais informações, consulte [Special objects](https://docs.aws.amazon.com//appsync/latest/devguide/graphql-types.html#special-object-components).

Como `getAuthor` e `getBook` estão solicitando dados, eles serão colocados em um tipo de objeto especial de `Query`:

```
type Author {
  authorName: String
  Books: [Book]
}

type Book {
  bookName: String
  Authors: [Author]
}

type Query {
  getAuthor(authorName: String): Author
  getBook(bookName: String): Book
}
```

As operações são vinculadas à consulta, que por sua vez está vinculada ao esquema. Adicionar uma raiz de esquema definirá o tipo de objeto especial (neste caso, `Query`) como um dos seus pontos de entrada. Isso pode ser feito usando a palavra-chave `schema`:

```
schema {
  query: Query
}

type Author {
  authorName: String
  Books: [Book]
}

type Book {
  bookName: String
  Authors: [Author]
}

type Query {
  getAuthor(authorName: String): Author
  getBook(bookName: String): Book
}
```

Analisando os últimos dois métodos, `addAuthor` e `addBook` estão adicionando informações ao seu banco de dados para que sejam definidos em um tipo de objeto especial `Mutation`. No entanto, na página [Tipos](https://docs.aws.amazon.com/appsync/latest/devguide/graphql-types.html#input-components), não é permitido usar entradas que fazem referência direta a objetos, porque são tipos de saída. Nesse caso, não podemos usar `Author` nem `Book`, então precisamos criar um tipo de entrada com os mesmos campos. Neste exemplo, adicionamos `AuthorInput` e `BookInput`, que aceitam os mesmos campos de seus respectivos tipos. Em seguida, criamos nossa mutação usando as entradas como nossos parâmetros:

```
schema {
  query: Query
  mutation: Mutation
}

type Author {
  authorName: String
  Books: [Book]
}

input AuthorInput {
  authorName: String
  Books: [BookInput]
}

type Book {
  bookName: String
  Authors: [Author]
}

input BookInput {
  bookName: String
  Authors: [AuthorInput]
}

type Query {
  getAuthor(authorName: String): Author
  getBook(bookName: String): Book
}

type Mutation {
  addAuthor(input: [BookInput]): Author
  addBook(input: [AuthorInput]): Book
}
```

Vamos analisar o que acabamos de fazer:

1. Criamos um esquema com os tipos `Author` e `Book` para representar nossas entidades.

1. Adicionamos os campos contendo as características de nossas entidades.

1. Adicionamos uma consulta para recuperar essas informações do banco de dados.

1. Adicionamos uma mutação para manipular dados no banco de dados.

1. Adicionamos tipos de entrada para substituir nossos parâmetros de objeto na mutação para cumprir as regras do GraphQL.

1. Adicionamos a consulta e a mutação ao nosso esquema raiz para que a implementação do GraphQL identifique a localização do tipo raiz.

Como você pode notar, o processo de criação de um esquema usa muitos conceitos da modelagem de dados (especialmente da modelagem de banco de dados) em geral. Podemos dizer que o esquema se ajusta à forma dos dados da fonte. Ele também serve como o modelo que o solucionador implementará. Nas seções a seguir, você aprenderá como criar um esquema usando várias ferramentas e AWS serviços suportados.

**nota**  
Os exemplos nas seções a seguir não devem ser executados em uma aplicação real. Eles apenas mostram os comandos para que você crie suas próprias aplicações.

## Criar esquemas
<a name="creating-schema"></a>

Seu esquema estará em um arquivo chamado`schema.graphql`. AWS AppSync permite que os usuários criem novos esquemas para seu APIs GraphQL usando vários métodos. Neste exemplo, criaremos uma API em branco junto com um esquema em branco.

------
#### [ Console ]

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

   1. No **Painel**, escolha **Criar API**.

   1. **Em **Opções de API**, escolha **GraphQL APIs**, **Design from scratch** e Next.**

      1. Para o **nome da API**, troque o nome pré-preenchido algo que seja necessário para a aplicação.

      1. Para **obter detalhes de contato**, você pode inserir um ponto de contato para identificar um gerente para a API. Esse é um campo opcional.

      1. Em **Configuração da API privada**, é possível habilitar os atributos da API privada. Uma API privada só pode ser acessada de um endpoint da VPC (VPCE) configurado. Para obter mais informações, consulte [Privado APIs](https://docs.aws.amazon.com/appsync/latest/devguide/using-private-apis.html).

         Não recomendamos habilitar esse atributo para este exemplo. Após analisar suas entradas, selecione **Próximo**.

   1. Em **Criar um tipo de GraphQL**, você pode criar uma tabela do DynamoDB para usar como fonte de dados ou ignorar e fazer isso depois.

      Para este exemplo, escolha **Criar recursos do GraphQL mais tarde**. Vamos criar um recurso em uma seção separada.

   1. Revise suas entradas e selecione **Criar API**.

1. Você estará no painel da sua API específica. É possível identificar o nome da API na parte superior do painel. Se esse não for o caso, você pode selecionar **APIs**na **barra lateral** e escolher sua API no **APIs painel**.

   1. Na **barra lateral** abaixo do nome da sua API, escolha **Esquema**.

1. Você pode configurar seu arquivo `schema.graphql` no **editor de esquemas**. Ele pode estar vazio ou preenchido com tipos gerados a partir de um modelo. À direita, você tem a seção **Solucionadores** para anexar solucionadores aos campos do esquema. Não examinaremos os solucionadores nesta seção.

------
#### [ CLI ]

**nota**  
Ao usar a CLI, verifique se você tem as permissões certas para acessar e criar recursos no serviço. Considere definir políticas de [privilégio mínimo](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege) para usuários não administradores que precisam acessar o serviço. Para obter mais informações sobre AWS AppSync políticas, consulte [Gerenciamento de identidade e acesso para AWS AppSync](https://docs.aws.amazon.com//appsync/latest/devguide/security-iam.html).  
Além disso, recomendamos primeiro ler a versão do console.

1. Caso ainda não tenha feito isso, [instale](https://docs.aws.amazon.com//cli/latest/userguide/cli-chap-getting-started.html) e configure o AWS CLI e adicione sua [configuração](https://docs.aws.amazon.com//cli/latest/userguide/cli-configure-quickstart.html).

1. Crie um objeto da API GraphQL executando o comando [https://docs.aws.amazon.com/cli/latest/reference/appsync/create-graphql-api.html](https://docs.aws.amazon.com/cli/latest/reference/appsync/create-graphql-api.html).

   Você precisará digitar dois parâmetros para esse comando específico:

   1. O `name` da sua API.

   1. O `authentication-type`, ou o tipo de credencial usado para acessar a API (IAM, OIDC etc.).
**nota**  
Outros parâmetros, como `Region` devem ser configurados, mas geralmente usam como padrão os valores de configuração da CLI.

   Veja um exemplo de comando:

   ```
   aws appsync create-graphql-api --name testAPI123 --authentication-type API_KEY
   ```

   Uma saída será retornada na CLI. Veja um exemplo abaixo:

   ```
   {
       "graphqlApi": {
           "xrayEnabled": false,
           "name": "testAPI123",
           "authenticationType": "API_KEY",
           "tags": {},
           "apiId": "abcdefghijklmnopqrstuvwxyz",
           "uris": {
               "GRAPHQL": "https://zyxwvutsrqponmlkjihgfedcba.appsync-api.us-west-2.amazonaws.com/graphql",
               "REALTIME": "wss://zyxwvutsrqponmlkjihgfedcba.appsync-realtime-api.us-west-2.amazonaws.com/graphql"
           },
           "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz"
       }
   }
   ```

1. 
**nota**  
Esse é um comando opcional que carrega um esquema existente no serviço do AWS AppSync usando um blob Base64. Não usaremos esse comando para preservar este exemplo.

   Execute o comando [https://docs.aws.amazon.com/cli/latest/reference/appsync/start-schema-creation.html](https://docs.aws.amazon.com/cli/latest/reference/appsync/start-schema-creation.html).

   Você precisará digitar dois parâmetros para esse comando específico:

   1. Seu `api-id` da etapa anterior.

   1. O esquema `definition` é um blob binário codificado com Base64.

   Veja um exemplo de comando:

   ```
    aws appsync start-schema-creation --api-id abcdefghijklmnopqrstuvwxyz --definition "aa1111aa-123b-2bb2-c321-12hgg76cc33v"
   ```

   Uma saída será retornada:

   ```
   {
       "status": "PROCESSING"
   }
   ```

   Esse comando não retornará a saída final depois do processamento. Você deve usar um comando separado, [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/get-schema-creation-status.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/get-schema-creation-status.html), para ver o resultado. Esses dois comandos são assíncronos, portanto, você pode verificar o status da saída mesmo durante a criação do esquema.

------
#### [ CDK ]

**dica**  
[Antes de usar o CDK, recomendamos revisar a [documentação oficial](https://docs.aws.amazon.com/cdk/v2/guide/home.html) do CDK junto com AWS AppSync a referência do CDK.](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
As etapas listadas abaixo mostram apenas um exemplo geral do trecho usado para adicionar um recurso específico. Isso **não** é uma solução funcional para seu código de produção. Também presumimos que você já tenha uma aplicação em funcionamento.

1. O ponto de partida do CDK é um pouco diferente. O ideal é que seu arquivo `schema.graphql` já tenha sido criado. Você só precisa criar um novo arquivo com a extensão `.graphql`. Ele pode ser um arquivo vazio.

1. Em geral, talvez seja necessário adicionar a diretiva de importação ao serviço que você está usando. Por exemplo, estas são as possíveis formas:

   ```
   import * as x from 'x'; # import wildcard as the 'x' keyword from 'x-service'
   import {a, b, ...} from 'c'; # import {specific constructs} from 'c-service'
   ```

   Para adicionar uma API GraphQL, seu arquivo de pilha precisa importar o serviço: AWS AppSync 

   ```
   import * as appsync from 'aws-cdk-lib/aws-appsync';
   ```
**nota**  
Isso significa que estamos importando todo o serviço com a palavra-chave `appsync`. Para usar isso em seu aplicativo, suas AWS AppSync construções usarão o formato`appsync.construct_name`. Por exemplo, se quiséssemos criar uma API GraphQL, teríamos um `new appsync.GraphqlApi(args_go_here)`. A etapa a seguir mostra isso.

1. A API mais básica do GraphQL incluirá um `name` para a API e o caminho do `schema`.

   ```
   const add_api = new appsync.GraphqlApi(this, 'API_ID', {
     name: 'name_of_API_in_console',
     schema: appsync.SchemaFile.fromAsset(path.join(__dirname, 'schema_name.graphql')),
   });
   ```
**nota**  
Vamos analisar o que esse trecho faz. Dentro do escopo da `api`, estamos criando uma nova API GraphQL chamando o `appsync.GraphqlApi(scope: Construct, id: string, props: GraphqlApiProps)`. O escopo é `this`, que se refere ao objeto atual. O id é*API\$1ID*, que será o nome do recurso da sua API GraphQL CloudFormation quando ela for criada. O `GraphqlApiProps` contém o `name` da sua API GraphQL e o `schema`. `schema`Isso gerará um esquema (`SchemaFile.fromAsset`) pesquisando o caminho absoluto (`__dirname`) do `.graphql` arquivo (*schema\$1name.graphql*). Em um cenário real, seu arquivo de esquema provavelmente estará na aplicação do CDK.  
Para usar as alterações feitas na sua API GraphQL, você precisará reimplantar a aplicação.

------

## Adicionar tipos aos esquemas
<a name="adding-schema-types"></a>

Agora que você adicionou seu esquema, pode começar a adicionar os tipos de entrada e saída. Os tipos aqui não devem ser usados em código real; eles são apenas exemplos para ajudar você a entender o processo.

Primeiro, vamos criar um tipo de objeto. No código real, não é necessário começar com esses tipos. Você pode criar o tipo que preferir a qualquer momento, desde que siga as regras e a sintaxe do GraphQL.

**nota**  
As próximas seções usarão o **editor de esquemas**, portanto, mantenha-o aberto.

------
#### [ Console ]
+ Você pode criar um tipo de objeto usando a palavra-chave `type` junto com o nome do tipo:

  ```
  type Type_Name_Goes_Here {}
  ```

  Dentro do escopo do tipo, você pode adicionar campos que representam as características do objeto:

  ```
  type Type_Name_Goes_Here {
    # Add fields here
  }
  ```

  Veja um exemplo abaixo:

  ```
  type Obj_Type_1 {
    id: ID!
    title: String
    date: AWSDateTime
  }
  ```
**nota**  
Nesta etapa, adicionamos um tipo de objeto genérico com um campo obrigatório `id` armazenado como `ID`, um campo `title` armazenado como `String`, e um campo `date` armazenado como `AWSDateTime`. Para visualizar uma lista de tipos e campos e o que eles fazem, consulte [Schemas](https://docs.aws.amazon.com//appsync/latest/devguide/schema-components.html). Para visualizar uma lista de escalares e o que eles fazem, consulte a [Type reference](https://docs.aws.amazon.com/appsync/latest/devguide/type-reference.html).

------
#### [ CLI ]

**nota**  
Recomendamos que seja feita a leitura da versão do console primeiro.
+ Você pode criar um tipo de objeto executando o comando [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html).

  Você precisará inserir alguns parâmetros para esse comando específico:

  1. O `api-id` da sua API.

  1. A `definition`, ou o conteúdo do seu tipo. No exemplo do console, tínhamos:

     ```
     type Obj_Type_1 {
       id: ID!
       title: String
       date: AWSDateTime
     }
     ```

  1. O `format` da sua entrada. Neste exemplo, usamos o `SDL`.

  Veja um exemplo de comando:

  ```
  aws appsync create-type --api-id abcdefghijklmnopqrstuvwxyz --definition "type Obj_Type_1{id: ID! title: String date: AWSDateTime}" --format SDL
  ```

  Uma saída será retornada na CLI. Veja um exemplo abaixo:

  ```
  {
      "type": {
          "definition": "type Obj_Type_1{id: ID! title: String date: AWSDateTime}",
          "name": "Obj_Type_1",
          "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Obj_Type_1",
          "format": "SDL"
      }
  }
  ```
**nota**  
Nesta etapa, adicionamos um tipo de objeto genérico com um campo obrigatório `id` armazenado como `ID`, um campo `title` armazenado como `String`, e um campo `date` armazenado como `AWSDateTime`. Para visualizar uma lista de tipos e campos e o que eles fazem, consulte [Schemas](https://docs.aws.amazon.com//appsync/latest/devguide/schema-components.html). Para visualizar uma lista de escalares e o que eles fazem, consulte [Type reference](https://docs.aws.amazon.com/appsync/latest/devguide/type-reference.html).  
Além disso, inserir a definição diretamente funciona para tipos menores, mas é inviável para adicionar tipos maiores ou vários tipos. Você pode adicionar tudo em um arquivo `.graphql` e depois [transmiti-lo como a entrada](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-parameters-file.html).

------
#### [ CDK ]

**dica**  
[Antes de usar o CDK, recomendamos revisar a [documentação oficial](https://docs.aws.amazon.com/cdk/v2/guide/home.html) do CDK junto com AWS AppSync a referência do CDK.](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
As etapas listadas abaixo mostram apenas um exemplo geral do trecho usado para adicionar um recurso específico. Isso **não** é uma solução funcional para seu código de produção. Também presumimos que você já tenha uma aplicação em funcionamento.

Para adicionar um tipo, você precisa adicioná-lo ao seu arquivo `.graphql`. Por exemplo, o exemplo do console foi:

```
type Obj_Type_1 {
  id: ID!
  title: String
  date: AWSDateTime
}
```

Você pode adicionar seus tipos diretamente ao esquema, como qualquer outro arquivo.

**nota**  
Para usar as alterações feitas na sua API GraphQL, você precisará reimplantar a aplicação.

------

O [tipo de objeto](https://graphql.org/learn/schema/#object-types-and-fields) tem campos que são [tipos escalares](https://graphql.org/learn/schema/#scalar-types), como cadeias de caracteres e números inteiros. AWS AppSync também permite que você use tipos escalares aprimorados, como `AWSDateTime` adição aos escalares básicos do GraphQL. Qualquer campo que termine com um ponto de exclamação é um campo obrigatório. 

O tipo de escalar `ID` é um identificador exclusivo que pode ser `String` ou `Int`. É possível controlar isso nos modelos de mapeamento do solucionador para atribuição automática.

Há semelhanças entre tipos de objetos especiais de `Query` e tipos de objetos “comuns”, como no exemplo acima, pois ambos usam a palavra-chave `type` e são considerados objetos. No entanto, para os tipos de objetos especiais (`Query`, `Mutation` e`Subscription`), o comportamento deles é muito diferente porque eles são expostos como pontos de entrada da sua API. Eles também priorizam a modelagem de operações em vez dos dados. Para obter mais informações, consulte [The query and mutation types](https://graphql.org/learn/schema/#the-query-and-mutation-types).

No tópico dos tipos de objetos especiais, a próxima etapa pode ser adicionar um ou mais deles para realizar operações nos dados modelados. Em um cenário real, todo esquema do GraphQL deve ter pelo menos um tipo de consulta-raiz para solicitar dados. Você pode pensar na consulta como um dos pontos de entrada (ou endpoints) do seu servidor do GraphQL. Vamos adicionar uma consulta como exemplo.

------
#### [ Console ]
+ Para criar uma consulta, basta adicioná-la ao arquivo do esquema como qualquer outro tipo. Uma consulta exigiria um tipo de `Query` e uma entrada na raiz como esta:

  ```
  schema {
    query: Name_of_Query
  }
  
  type Name_of_Query {
    # Add field operation here
  }
  ```

  Observe que *Name\$1of\$1Query* em um ambiente de produção simplesmente será chamado `Query` na maioria dos casos. Recomendamos manter esse valor baixo. Dentro do tipo de consulta, você pode adicionar campos. Cada campo executará uma operação na solicitação. Como resultado, a maioria desses campos, se não todos, serão anexados a um solucionador. No entanto, não vamos abordar esse assunto nesta seção. Em relação ao formato da operação do campo, ela pode ser como esta:

  ```
  Name_of_Query(params): Return_Type # version with params
  Name_of_Query: Return_Type # version without params
  ```

  Veja um exemplo abaixo:

  ```
  schema {
    query: Query
  }
  
  type Query {
    getObj: [Obj_Type_1]
  }
  
  type Obj_Type_1 {
    id: ID!
    title: String
    date: AWSDateTime
  }
  ```
**nota**  
Nesta etapa, adicionamos um tipo de `Query` e o definimos na raiz do nosso `schema`. Nosso tipo de `Query` definiu um campo `getObj` que retorna uma lista de objetos `Obj_Type_1`. Esse `Obj_Type_1` é o objeto da etapa anterior. No código de produção, suas operações de campo normalmente trabalharão com dados moldados por objetos como `Obj_Type_1`. Além disso, campos como `getObj` normalmente terão um solucionados para executar a lógica de negócios. Isso será abordado em outra seção.  
Como observação adicional, adiciona AWS AppSync automaticamente uma raiz do esquema durante as exportações, então, tecnicamente, você não precisa adicioná-la diretamente ao esquema. Nosso serviço processará esquemas duplicados de maneira automática. Essa é uma prática recomendada.

------
#### [ CLI ]

**nota**  
Recomendamos que seja feita a leitura da versão do console primeiro.

1. Crie um `schema` raiz com uma definição da `query` executando o comando [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html).

   Você precisará inserir alguns parâmetros para esse comando específico:

   1. O `api-id` da sua API.

   1. A `definition`, ou o conteúdo do seu tipo. No exemplo do console, tínhamos:

      ```
      schema {
        query: Query
      }
      ```

   1. O `format` da sua entrada. Neste exemplo, usamos o `SDL`.

   Veja um exemplo de comando:

   ```
   aws appsync create-type --api-id abcdefghijklmnopqrstuvwxyz --definition "schema {query: Query}" --format SDL
   ```

   Uma saída será retornada na CLI. Veja um exemplo abaixo:

   ```
   {
       "type": {
           "definition": "schema {query: Query}",
           "name": "schema",
           "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/schema",
           "format": "SDL"
       }
   }
   ```
**nota**  
Se você tiver cometido um erro no comando `create-type`, poderá atualizar a raiz do esquema (ou qualquer tipo no esquema) executando o comando [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-type.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-type.html). Neste exemplo, alteraremos temporariamente a raiz do esquema para conter uma definição de `subscription`.  
Você precisará inserir alguns parâmetros para esse comando específico:  
O `api-id` da sua API.
O `type-name` do seu tipo. No exemplo do console, tínhamos `schema`.
A `definition`, ou o conteúdo do seu tipo. No exemplo do console, tínhamos:  

      ```
      schema {
        query: Query
      }
      ```
O esquema após a adição de um `subscription` será semelhante a este:  

      ```
      schema {
        query: Query
        subscription: Subscription
      }
      ```
O `format` da sua entrada. Neste exemplo, usamos o `SDL`.
Veja um exemplo de comando:  

   ```
   aws appsync update-type --api-id abcdefghijklmnopqrstuvwxyz --type-name schema --definition "schema {query: Query subscription: Subscription}" --format SDL
   ```
Uma saída será retornada na CLI. Veja um exemplo abaixo:  

   ```
   {
       "type": {
           "definition": "schema {query: Query subscription: Subscription}",
           "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/schema",
           "format": "SDL"
       }
   }
   ```
Adicionar arquivos pré-formatados ainda funcionará neste exemplo.

1. Crie uma `Query` executando o comando [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html).

   Você precisará inserir alguns parâmetros para esse comando específico:

   1. O `api-id` da sua API.

   1. A `definition`, ou o conteúdo do seu tipo. No exemplo do console, tínhamos:

      ```
      type Query {
        getObj: [Obj_Type_1]
      }
      ```

   1. O `format` da sua entrada. Neste exemplo, usamos o `SDL`.

   Veja um exemplo de comando:

   ```
   aws appsync create-type --api-id abcdefghijklmnopqrstuvwxyz --definition "type Query {getObj: [Obj_Type_1]}" --format SDL
   ```

   Uma saída será retornada na CLI. Veja um exemplo abaixo:

   ```
   {
       "type": {
           "definition": "Query {getObj: [Obj_Type_1]}",
           "name": "Query",
           "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Query",
           "format": "SDL"
       }
   }
   ```
**nota**  
Nesta etapa, adicionamos um tipo de `Query` e o definimos na raiz do seu `schema`. Nosso tipo de `Query` definiu um campo `getObj` que retornou uma lista de objetos `Obj_Type_1`.  
Na `query: Query` do código-raiz do `schema`, a parte `query:` indica que uma consulta foi definida em seu esquema, enquanto a parte `Query` representa o nome real do objeto especial. 

------
#### [ CDK ]

**dica**  
[Antes de usar o CDK, recomendamos revisar a [documentação oficial](https://docs.aws.amazon.com/cdk/v2/guide/home.html) do CDK junto com AWS AppSync a referência do CDK.](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
As etapas listadas abaixo mostram apenas um exemplo geral do trecho usado para adicionar um recurso específico. Isso **não** é uma solução funcional para seu código de produção. Também presumimos que você já tenha uma aplicação em funcionamento.

Você precisará adicionar sua consulta e a raiz do esquema ao arquivo do `.graphql`. Nosso exemplo se parece com o exemplo abaixo, mas considere substituí-lo pelo código do seu esquema real:

```
schema {
  query: Query
}

type Query {
  getObj: [Obj_Type_1]
}

type Obj_Type_1 {
  id: ID!
  title: String
  date: AWSDateTime
}
```

Você pode adicionar seus tipos diretamente ao esquema, como qualquer outro arquivo.

**nota**  
A atualização da raiz do esquema é opcional. Nós a adicionamos a esse exemplo como uma prática recomendada.  
Para usar as alterações feitas na sua API GraphQL, você precisará reimplantar a aplicação.

------

Mostramos um exemplo de criação de objetos comuns e objetos especiais (consultas). Também abordamos como eles se interconectam para descrever dados e operações. Pode haver esquemas apenas com a descrição dos dados e uma ou mais consultas. No entanto, gostaríamos de adicionar outra operação para incluir dados na fonte de dados. Adicionaremos outro tipo de objeto especial chamado `Mutation` que modifica os dados.

------
#### [ Console ]
+ Uma mutação será chamada de `Mutation`. Como a `Query`, as operações de campo em `Mutation` descrevem uma operação e serão anexadas a um solucionador. Além disso, precisamos defini-lo na raiz do `schema` porque é um tipo de objeto especial. Veja um exemplo de mutação abaixo:

  ```
  schema {
    mutation: Name_of_Mutation
  }
  
  type Name_of_Mutation {
    # Add field operation here
  }
  ```

  Uma mutação típica será listada na raiz como uma consulta. A mutação é definida usando a `type` palavra-chave junto com o nome. *Name\$1of\$1Mutation*normalmente serão chamados`Mutation`, por isso recomendamos que continue assim. Cada campo também executará uma operação. Em relação ao formato da operação do campo, ela pode ser como esta:

  ```
  Name_of_Mutation(params): Return_Type # version with params
  Name_of_Mutation: Return_Type # version without params
  ```

  Veja um exemplo abaixo:

  ```
  schema {
    query: Query
    mutation: Mutation
  }
  
  type Obj_Type_1 {
    id: ID!
    title: String
    date: AWSDateTime
  }
  
  type Query {
    getObj: [Obj_Type_1]
  }
  
  type Mutation {
    addObj(id: ID!, title: String, date: AWSDateTime): Obj_Type_1
  }
  ```
**nota**  
Nesta etapa, adicionamos um tipo de `Mutation` com um campo `addObj`. Vamos resumir o que esse campo faz:  

  ```
  addObj(id: ID!, title: String, date: AWSDateTime): Obj_Type_1
  ```
O `addObj` usa o objeto `Obj_Type_1` para realizar uma operação. Isso é evidente ao observar os campos, mas a sintaxe prova isso no tipo de retorno `: Obj_Type_1`. Em `addObj`, os campos `id`, `title` e `date` do objeto `Obj_Type_1` como parâmetros. Como podemos notar, ela se parece muito com uma declaração de método. No entanto, ainda não descrevemos o comportamento do nosso método. Conforme mencionado anteriormente, o esquema só existe para definir quais serão os dados e as operações e não a forma como operam. A implementação da lógica de negócios real será abordada quando criarmos nossos primeiros solucionadores.  
Depois de concluir o esquema, há uma opção para exportá-lo como um arquivo `schema.graphql`. No **Editor de esquemas**, você pode escolher **Exportar esquema** para fazer download do arquivo em um formato compatível.  
Como observação adicional, adiciona AWS AppSync automaticamente uma raiz do esquema durante as exportações, então, tecnicamente, você não precisa adicioná-la diretamente ao esquema. Nosso serviço processará esquemas duplicados de maneira automática. Essa é uma prática recomendada.

------
#### [ CLI ]

**nota**  
Recomendamos que seja feita a leitura da versão do console primeiro.

1. Atualize seu esquema-raiz executando o comando [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-type.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-type.html).

   Você precisará inserir alguns parâmetros para esse comando específico:

   1. O `api-id` da sua API.

   1. O `type-name` do seu tipo. No exemplo do console, tínhamos `schema`.

   1. A `definition`, ou o conteúdo do seu tipo. No exemplo do console, tínhamos:

      ```
      schema {
        query: Query
        mutation: Mutation
      }
      ```

   1. O `format` da sua entrada. Neste exemplo, usamos o `SDL`.

   Veja um exemplo de comando:

   ```
   aws appsync update-type --api-id abcdefghijklmnopqrstuvwxyz --type-name schema --definition "schema {query: Query mutation: Mutation}" --format SDL
   ```

   Uma saída será retornada na CLI. Veja um exemplo abaixo:

   ```
   {
       "type": {
           "definition": "schema {query: Query mutation: Mutation}",
           "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/schema",
           "format": "SDL"
       }
   }
   ```

1. Crie uma `Mutation` executando o comando [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-type.html).

   Você precisará inserir alguns parâmetros para esse comando específico:

   1. O `api-id` da sua API.

   1. A `definition`, ou o conteúdo do seu tipo. No exemplo do console, tínhamos

      ```
      type Mutation {
        addObj(id: ID!, title: String, date: AWSDateTime): Obj_Type_1
      }
      ```

   1. O `format` da sua entrada. Neste exemplo, usamos o `SDL`.

   Veja um exemplo de comando:

   ```
   aws appsync create-type --api-id abcdefghijklmnopqrstuvwxyz --definition "type Mutation {addObj(id: ID! title: String date: AWSDateTime): Obj_Type_1}" --format SDL
   ```

   Uma saída será retornada na CLI. Veja um exemplo abaixo:

   ```
   {
       "type": {
           "definition": "type Mutation {addObj(id: ID! title: String date: AWSDateTime): Obj_Type_1}",
           "name": "Mutation",
           "arn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Mutation",
           "format": "SDL"
       }
   }
   ```

------
#### [ CDK ]

**dica**  
[Antes de usar o CDK, recomendamos revisar a [documentação oficial](https://docs.aws.amazon.com/cdk/v2/guide/home.html) do CDK junto com AWS AppSync a referência do CDK.](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
As etapas listadas abaixo mostram apenas um exemplo geral do trecho usado para adicionar um recurso específico. Isso **não** é uma solução funcional para seu código de produção. Também presumimos que você já tenha uma aplicação em funcionamento.

Você precisará adicionar sua consulta e a raiz do esquema ao arquivo do `.graphql`. Nosso exemplo se parece com o exemplo abaixo, mas considere substituí-lo pelo código do seu esquema real:

```
schema {
  query: Query
  mutation: Mutation
}

type Obj_Type_1 {
  id: ID!
  title: String
  date: AWSDateTime
}

type Query {
  getObj: [Obj_Type_1]
}

type Mutation {
  addObj(id: ID!, title: String, date: AWSDateTime): Obj_Type_1
}
```

**nota**  
A atualização da raiz do esquema é opcional. Nós a adicionamos a esse exemplo como uma prática recomendada.  
Para usar as alterações feitas na sua API GraphQL, você precisará reimplantar a aplicação.

------

## Considerações opcionais: usar enumerados como status
<a name="optional-consideration-enums"></a>

Neste ponto, você já sabe como criar um esquema básico. No entanto, há muitos elementos que você pode adicionar para aumentar a funcionalidade do esquema. Uma coisa comum encontrada nas aplicações é o uso de enumerados como status. Você pode usar um enumerado para aplicar um valor específico de um conjunto de valores a ser escolhido quando chamado. Isso é bom para elementos que não mudarão drasticamente por longos períodos. Hipoteticamente falando, poderíamos adicionar um enumerado que retorna o código de status ou string na resposta. 

Como exemplo, vamos supor que estamos criando uma aplicação de mídia social que armazena os dados de postagem de um usuário no back-end. Nosso esquema contém um tipo de `Post` que representa os dados de uma postagem individual:

```
type Post {
  id: ID!
  title: String
  date: AWSDateTime
  poststatus: PostStatus
}
```

Nossa `Post` conterá um único `id`, um `title`, uma `date` de postagem e um enumerado chamado de `PostStatus`, que representa o estado da postagem conforme ela é processada pela aplicação. Para nossas operações, teremos uma consulta que retornará todos os dados da postagem:

```
type Query {
  getPosts: [Post]
}
```

Também teremos uma mutação que adiciona postagens à fonte de dados:

```
type Mutation {
  addPost(id: ID!, title: String, date: AWSDateTime, poststatus: PostStatus): Post
}
```

Analisando nosso esquema, o enumerado `PostStatus` pode ter vários status. É possível termos os três estados básicos chamados de `success` (postagem processada com sucesso), `pending` (postagem sendo processada) e `error` (postagem que não foi processada). Para adicionar o enumerado, podemos fazer o seguinte:

```
enum PostStatus {
  success
  pending
  error
}
```

O esquema completo pode ser semelhante a este:

```
schema {
  query: Query
  mutation: Mutation
}

type Post {
  id: ID!
  title: String
  date: AWSDateTime
  poststatus: PostStatus
}

type Mutation {
  addPost(id: ID!, title: String, date: AWSDateTime, poststatus: PostStatus): Post
}

type Query {
  getPosts: [Post]
}

enum PostStatus {  
  success
  pending
  error
}
```

Se um usuário adicionar uma `Post` à aplicação, a operação `addPost` será chamada para processar esses dados. À medida que o solucionador anexado à `addPost` processa os dados, ele vai atualizar o `poststatus` continuamente com o status da operação. Quando consultado, a `Post` vai mostrar o status final dos dados. Aqui só descrevemos como queremos que os dados funcionem no esquema. Fazemos muitas suposições sobre a implementação de nossos solucionadores, que implementarão a lógica comercial real para lidar com os dados e atender à solicitação.

## Considerações opcionais: assinaturas
<a name="optional-consideration-subscriptions"></a>

As assinaturas em AWS AppSync são invocadas como resposta a uma mutação. Isso pode ser configurado com um tipo `Subscription` e diretiva `@aws_subscribe()` no esquema para indicar quais mutações invocam uma ou mais assinaturas. Consulte [Real-time data](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-data.html) para obter mais informações sobre como configurar assinaturas.

## Considerações opcionais: relações e paginação
<a name="optional-consideration-relations-and-pagination"></a>

Suponha que você tenha um milhão de `Posts` armazenadas em uma tabela do DynamoDB e queira retornar alguns desses dados. No entanto, o exemplo de consulta fornecido acima retorna todas as postagens. Não é fácil buscar tudo isso sempre que fizer uma solicitação. O melhor é [paginar](https://graphql.org/learn/pagination/) todas elas. Faça as seguintes alterações ao esquema:
+ No campo `getPosts`, adicione dois argumentos de entrada: `nextToken` (iterador) e `limit` (limite de iteração).
+ Adicione um novo tipo de `PostIterator` contendo `Posts` (isso recupera a lista de objetos `Post`) e campos `nextToken` (iterador).
+ Altere `getPosts` para que retorne `PostIterator`, não uma lista de objetos `Post`.

```
schema {
  query: Query
  mutation: Mutation
}

type Post {
  id: ID!
  title: String
  date: AWSDateTime
  poststatus: PostStatus
}

type Mutation {
  addPost(id: ID!, title: String, date: AWSDateTime, poststatus: PostStatus): Post
}

type Query {
  getPosts(limit: Int, nextToken: String): PostIterator
}

enum PostStatus {
  success
  pending
  error
}

type PostIterator {
  posts: [Post]
  nextToken: String
}
```

O tipo `PostIterator` permite que você retorne parte da lista de objetos de `Post` e um `nextToken` para obter a próxima parte. Em `PostIterator`, há uma lista de itens da `Post` (`[Post]`) que é retornada com um token de paginação (`nextToken`). Em AWS AppSync, isso seria conectado ao Amazon DynamoDB por meio de um resolvedor e gerado automaticamente como um token criptografado. Isso converte o valor do argumento `limit` no parâmetro `maxResults` e o argumento `nextToken` no parâmetro `exclusiveStartKey`. Para ver exemplos e exemplos de modelos integrados no AWS AppSync console, consulte [Referência do Resolver (JavaScript)](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html).

# Anexando uma fonte de dados em AWS AppSync
<a name="attaching-a-data-source"></a>

As fontes de dados são recursos em sua AWS conta com os quais o GraphQL APIs pode interagir. AWS AppSync oferece suporte a várias fontes de dados AWS Lambda, como Amazon DynamoDB, bancos de dados relacionais (Amazon Aurora Serverless), Amazon Service e endpoints HTTP. OpenSearch Uma AWS AppSync API pode ser configurada para interagir com várias fontes de dados, permitindo que você agregue dados em um único local. AWS AppSync pode usar AWS recursos existentes da sua conta ou provisionar tabelas do DynamoDB em seu nome a partir de uma definição de esquema.

A seção a seguir mostrará como anexar uma fonte de dados à sua API GraphQL.

## Tipos de fontes de dados
<a name="data-source-types"></a>

Agora que você criou um esquema no AWS AppSync console, você pode anexar uma fonte de dados a ele. Quando você começa a criar uma API, há a opção de provisionar uma tabela do Amazon DynamoDB durante a criação do esquema predefinido. No entanto, não abordaremos essa opção nesta seção. Você pode ver um exemplo disso na seção [Iniciar um esquema](https://docs.aws.amazon.com//appsync/latest/devguide/schema-launch-start.html).

Em vez disso, analisaremos todos os AWS AppSync suportes de fontes de dados. Há muitos fatores que influenciam a escolha da solução certa para seu aplicativo. As seções abaixo fornecerão contexto adicional para cada fonte de dados. Para obter informações gerais sobre fontes de dados, consulte [Data sources](https://docs.aws.amazon.com/appsync/latest/devguide/data-source-components.html).

### Amazon DynamoDB
<a name="data-source-type-ddb"></a>

O Amazon DynamoDB é uma das principais soluções AWS de armazenamento para aplicativos escaláveis. O componente principal do DynamoDB é a **tabela**, que é simplesmente um conjunto de dados. Normalmente, você cria tabelas com base em entidades como `Book` ou `Author`. As informações de entrada da tabela são armazenadas como **itens**, que são grupos de campos exclusivos para cada entrada. Um item completo representa um row/record no banco de dados. Por exemplo, um item para uma entrada da `Book` pode incluir `title` e `author` com seus valores. Os campos individuais, como `title` e, `author` são chamados de **atributos**, que são semelhantes aos valores das colunas em bancos de dados relacionais. 

Como você pode imaginar, as tabelas serão usadas para armazenar dados do seu aplicativo. AWS AppSync permite que você conecte suas tabelas do DynamoDB à sua API do GraphQL para manipular dados. Veja este [caso de uso](https://aws.amazon.com/blogs/mobile/new-real-time-multi-group-app-with-aws-amplify-graphql-build-a-twitter-community-clone/) no blog *Front-end web and mobile*. Esta aplicação permite que os usuários se inscrevam em um aplicativo de mídia social. Os usuários podem participar de grupos e fazer upload de postagens que são transmitidas para outros usuários inscritos no grupo. A aplicação armazena informações de usuários, publicações e grupos de usuários no DynamoDB. A API GraphQL (gerenciada por AWS AppSync) faz interface com a tabela do DynamoDB. Quando um usuário faz uma alteração no sistema que será refletida no front-end, a API GraphQL recupera essas alterações e as transmite para outros usuários em tempo real.

### AWS Lambda
<a name="data-source-type-lam"></a>

O Lambda é um serviço orientado por eventos que cria automaticamente os recursos necessários para executar códigos como resposta a um evento. O Lambda usa **funções**, que são declarações de grupo contendo o código, as dependências e as configurações para executar um recurso. As funções são executadas automaticamente quando detectam um **gatilho**, um grupo de atividades que invocam sua função. Um gatilho pode ser algo como um aplicativo fazendo uma chamada de API, um AWS serviço em sua conta gerando um recurso etc. Quando acionadas, as funções processarão **eventos**, que são documentos JSON com os dados a serem modificados.

O Lambda é bom para executar códigos sem precisar provisionar os recursos para executá-lo. Veja este [caso de uso](https://aws.amazon.com/blogs/mobile/building-a-graphql-api-with-java-and-aws-lambda/) no blog *Front-end web and mobile*. Esse caso de uso é um pouco semelhante ao apresentado na seção do DynamoDB. Nessa aplicação, a API GraphQL é responsável por definir as operações para coisas como adicionar postagens (mutações) e buscar esses dados (consultas). Para implementar a funcionalidade de suas operações (por exemplo, `getPost ( id: String ! ) : Post` e `getPostsByAuthor ( author: String ! ) : [ Post ]`), eles usam funções do Lambda para processar solicitações de entrada. Na *Opção 2: AWS AppSync com o resolvedor Lambda*, eles usam o AWS AppSync serviço para manter seu esquema e vincular uma fonte de dados Lambda a uma das operações. Quando a operação é chamada, o Lambda interage com o Amazon RDS Proxy para executar a lógica de negócios no banco de dados.

### Amazon RDS
<a name="data-source-type-RDS"></a>

O Amazon RDS permite que você crie e configure rapidamente bancos de dados relacionais. No Amazon RDS, você criará uma **instância de banco de dados** genérica que servirá como ambiente de banco de dados isolado na nuvem. Nesta instância, você usará um **mecanismo de banco de dados**, que é o software RDBMS real (PostgreSQL, MySQL etc.). O serviço elimina grande parte do trabalho de back-end, fornecendo escalabilidade usando AWS infraestrutura, serviços de segurança, como patches e criptografia, e reduzindo os custos administrativos das implantações.

Veja o mesmo [caso de uso](https://aws.amazon.com/blogs/mobile/building-a-graphql-api-with-java-and-aws-lambda/) da seção do Lambda. Na *Opção 3: AWS AppSync com o resolvedor do Amazon RDS*, outra opção apresentada é vincular a API do GraphQL diretamente ao AWS AppSync Amazon RDS. Com uma [API de dados](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/data-api.html), eles associam o banco de dados à API GraphQL. Um resolvedor é anexado a um campo (geralmente uma consulta, mutação ou assinatura) e implementa as instruções SQL necessárias para acessar o banco de dados. Quando uma solicitação de chamada do campo é feita pelo cliente, o resolvedor executa as instruções e retorna a resposta.

### Amazon EventBridge
<a name="data-source-type-eventbridge"></a>

Em EventBridge, você criará **barramentos de eventos**, que são pipelines que recebem eventos de serviços ou aplicativos anexados (a **origem do evento**) e os processam com base em um conjunto de regras. Um **evento** é uma mudança de estado em um ambiente de execução, enquanto uma **regra** é um conjunto de filtros para eventos. Uma regra segue um **padrão de evento** ou metadados da mudança de estado de um evento (id, região, número da conta, ARN(s) etc.). Quando um evento corresponde ao padrão do evento, EventBridge enviará o evento pelo pipeline até o serviço de destino (**destino**) e acionará a ação especificada na regra.

EventBridge é bom para rotear operações de mudança de estado para algum outro serviço. Veja este [caso de uso](https://aws.amazon.com/blogs/mobile/appsync-eventbridge/) no blog *Front-end web and mobile*. O exemplo mostra uma solução de comércio eletrônico que tem várias equipes mantendo serviços diferentes. Um desses serviços fornece atualizações de pedidos ao cliente em cada etapa da entrega (pedido feito, em andamento, enviado, entregue etc.) no front-end. No entanto, a equipe de front-end que gerencia esse serviço não tem acesso direto aos dados do sistema de pedidos, pois eles são mantidos por uma equipe de back-end separada. O sistema de pedidos da equipe de back-end também é descrito como uma caixa preta, por isso, é difícil coletar informações sobre a forma como eles estruturam os dados. No entanto, a equipe de back-end configurou um sistema que publicou dados de pedidos por meio de um barramento de eventos gerenciado por EventBridge. Para acessar os dados provenientes do barramento de eventos e encaminhá-los para o front-end, a equipe de front-end criou um novo alvo apontando para a API GraphQL instalada. AWS AppSync Eles também criaram uma regra para enviar apenas dados relevantes para a atualização do pedido. Quando uma atualização é feita, os dados do barramento de eventos são enviados para a API GraphQL. O esquema na API processa os dados e os transfere para o front-end.

### Nenhuma fonte de dados
<a name="data-source-type-none"></a>

Se você não planeja usar uma fonte de dados, pode defini-la como `none`. Uma fonte de dados `none`, embora ainda seja explicitamente categorizada como fonte de dados, não é um meio de armazenamento. Normalmente, um resolvedor invoca uma ou mais fontes de dados em algum momento para processar a solicitação. No entanto, há situações em que talvez você não precise manipular uma fonte de dados. Definir a fonte de dados como `none` vai executar a solicitação, ignorar a etapa de invocação de dados e executar a resposta.

Veja o mesmo [caso de uso](https://aws.amazon.com/blogs/mobile/appsync-eventbridge/) da EventBridge seção. No esquema, a mutação processa a atualização de status e a envia aos assinantes. Semelhante ao funcionamento dos resolvedores, geralmente há pelo menos uma invocação de fonte de dados. No entanto, os dados nesse cenário já foram enviados automaticamente pelo barramento de eventos. Isso significa que não é necessário passar pela mutação para realizar uma invocação da fonte de dados; o status do pedido pode ser tratado localmente. A mutação é definida como `none`, o que funciona como um valor de passagem sem invocação da fonte de dados. O esquema é preenchido com os dados, que são enviados aos assinantes.

### OpenSearch
<a name="data-source-type-opensearch"></a>

O Amazon OpenSearch Service é um conjunto de ferramentas para implementar pesquisa de texto completo, visualização de dados e registro. Você pode usar esse serviço para consultar os dados estruturados que enviou.

Nesse serviço, você criará instâncias de OpenSearch. Eles são chamados de **nós**. Em um nó, você adicionará pelo menos um **índice**. Conceitualmente, os índices são um pouco como tabelas em bancos de dados relacionais. (No entanto, OpenSearch não é compatível com ACID, então não deve ser usado dessa forma). Você preencherá seu índice com os dados que você envia para o OpenSearch serviço. Quando seus dados forem carregados, eles serão indexados em um ou mais fragmentos existentes no índice. Um **fragmento** é como uma partição do seu índice que contém alguns dos seus dados e pode ser consultado separadamente de outros fragmentos. Depois de carregados, seus dados serão estruturados como arquivos JSON chamados **documentos**. Em seguida, você pode consultar o nó em busca de dados no documento.

### Endpoints de HTTP
<a name="data-source-type-http"></a>

Você pode usar endpoints HTTP como fontes de dados. AWS AppSync pode enviar solicitações aos endpoints com as informações relevantes, como parâmetros e carga útil. A resposta HTTP será exposta ao resolvedor, que retornará a resposta final após concluir suas operações.

## Adicionar uma fonte de dados
<a name="adding-a-data-source"></a>

Se você criou uma fonte de dados, pode vinculá-la ao AWS AppSync serviço e, mais especificamente, à API.

------
#### [ Console ]

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

   1. Escolha sua API no **Painel**.

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

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

   1. Dê um nome à sua fonte de dados. Você também pode incluir uma descrição, mas isso é opcional.

   1. Selecione o **tipo de fonte de dados**.

   1. Para o DynamoDB, você precisará escolher sua Região e, em seguida, a tabela na Região. Você pode definir regras de interação com sua tabela criando um novo perfil genérico ou importando um perfil existente. Você pode habilitar o [versionamento](https://docs.aws.amazon.com/appsync/latest/devguide/conflict-detection-and-sync.html), que pode criar automaticamente versões de dados para cada solicitação quando vários clientes estão tentando atualizar os dados ao mesmo tempo. O versionamento é usado para manter diversas variantes de dados para fins de detecção e resolução de conflitos. Você também pode ativar a geração automática de esquemas, que usa sua fonte de dados e gera parte do CRUD, `List` e `Query` das operações necessárias para acessá-la em seu esquema. 

      Para isso OpenSearch, você terá que escolher sua região e, em seguida, o domínio (cluster) na região. Você pode definir regras de interação com seu domínio criando uma nova função genérica ou importando uma função existente. 

      Para o Lambda, você terá que escolher sua Região e, em seguida, o ARN da função do Lambda na Região. Você pode definir regras de interação com sua função do Lambda criando um novo perfil da tabela genérica ou importando um perfil existente. 

      Para HTTP, você precisará inserir seu endpoint HTTP.

      Pois EventBridge, você terá que escolher sua região e, em seguida, o ônibus do evento na região. Você pode definir regras de interação com seu barramento de eventos, criando uma nova função genérica ou importando uma função existente. 

      Para o RDS, você precisará escolher sua Região, depois o armazenamento secreto (nome de usuário e senha), nome do banco de dados e esquema.

      Para nenhum deles, você adicionará uma fonte de dados sem uma fonte de dados real. Isso serve para lidar com resolvedores localmente, e não por meio de uma fonte de dados real.
**nota**  
Se você estiver importando funções existentes, elas precisarão de uma política de confiança. Para obter mais informações sobre a política de confiança, consulte [política de confiança do IAM](#iam-trust-policy.title).

1. Escolha **Criar**.
**nota**  
Como alternativa, se você estiver criando uma fonte de dados do DynamoDB, acesse a página **Esquema** no console, escolha **Criar recursos** na parte superior da página e preencha um modelo predefinido para converter em uma tabela. Nessa opção, você vai preencher ou importar o tipo de base, configurar os dados básicos da tabela, incluindo a chave de partição, além de analisar as alterações do esquema.

------
#### [ CLI ]
+ Crie um objeto da fonte de dados executando o comando [https://docs.aws.amazon.com/cli/latest/reference/appsync/create-data-source.html](https://docs.aws.amazon.com/cli/latest/reference/appsync/create-data-source.html).

  Você precisará inserir alguns parâmetros para esse comando específico:

  1. O `api-id` da sua API.

  1. O `name` da tabela.

  1. O `type` da fonte de dados. Dependendo do tipo de fonte de dados escolhido, talvez seja necessário inserir um `-config` e uma tag `service-role-arn`.

  Veja um exemplo de comando:

  ```
   aws appsync create-data-source --api-id abcdefghijklmnopqrstuvwxyz --name data_source_name --type data_source_type --service-role-arn arn:aws:iam::107289374856:role/role_name --[data_source_type]-config {params}
  ```

------
#### [ CDK ]

**dica**  
[Antes de usar o CDK, recomendamos revisar a [documentação oficial](https://docs.aws.amazon.com/cdk/v2/guide/home.html) do CDK junto com AWS AppSync a referência do CDK.](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
As etapas listadas abaixo mostram apenas um exemplo geral do trecho usado para adicionar um recurso específico. Isso **não** é uma solução funcional para seu código de produção. Também presumimos que você já tenha uma aplicação em funcionamento.

Para adicionar sua fonte de dados específica, você precisará incluir a estrutura ao seu arquivo de pilha. Uma lista dos tipos de fontes de dados pode ser encontrada aqui:
+  [ DynamoDbDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.DynamoDbDataSource.html) 
+  [ EventBridgeDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.EventBridgeDataSource.html) 
+  [ HttpDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.HttpDataSource.html) 
+  [ LambdaDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.LambdaDataSource.html) 
+  [ NoneDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.NoneDataSource.html) 
+  [ OpenSearchDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.OpenSearchDataSource.html) 
+  [ RdsDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.RdsDataSource.html) 

1. Em geral, talvez seja necessário adicionar a diretiva de importação ao serviço que você está usando. Por exemplo, estas são as possíveis formas:

   ```
   import * as x from 'x'; # import wildcard as the 'x' keyword from 'x-service'
   import {a, b, ...} from 'c'; # import {specific constructs} from 'c-service'
   ```

   Por exemplo, veja como você pode importar os serviços AWS AppSync e do DynamoDB:

   ```
   import * as appsync from 'aws-cdk-lib/aws-appsync';
   import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
   ```

1. Alguns serviços, como o RDS, exigem alguma configuração adicional no arquivo de pilha antes de criar a fonte de dados (por exemplo, criação de VPC, funções e credenciais de acesso). Consulte os exemplos nas páginas relevantes do CDK para obter mais informações.

1. Para a maioria das fontes de dados, especialmente AWS serviços, você criará uma nova instância da fonte de dados em seu arquivo de pilha. Normalmente, isso será exibido da seguinte forma:

   ```
   const add_data_source_func = new service_scope.resource_name(scope: Construct, id: string, props: data_source_props);
   ```

   Por exemplo, aqui está um exemplo de tabela do Amazon DynamoDB:

   ```
   const add_ddb_table = new dynamodb.Table(this, 'Table_ID', {
     partitionKey: {
       name: 'id',
       type: dynamodb.AttributeType.STRING,
     },
     sortKey: {
       name: 'id',
       type: dynamodb.AttributeType.STRING,
     },
     tableClass: dynamodb.TableClass.STANDARD,
   });
   ```
**nota**  
A maioria das fontes de dados terá pelo menos um suporte obrigatório (será indicado **sem** um símbolo `?`). Consulte a documentação do CDK para ver quais propriedades são necessárias.

1. Em seguida, você precisa vincular a fonte de dados à API GraphQL. O método recomendado é adicioná-la ao criar uma função para o resolvedor de pipeline. Por exemplo, o trecho abaixo é uma função que verifica todos os elementos em uma tabela do DynamoDB:

   ```
   const add_func = new appsync.AppsyncFunction(this, 'func_ID', {
     name: 'func_name_in_console',
     add_api,
     dataSource: add_api.addDynamoDbDataSource('data_source_name_in_console', add_ddb_table),
     code: appsync.Code.fromInline(`
         export function request(ctx) {
           return { operation: 'Scan' };
         }
   
         export function response(ctx) {
           return ctx.result.items;
         }
     `),
     runtime: appsync.FunctionRuntime.JS_1_0_0,
   });
   ```

   Nas propriedades de `dataSource`, você pode chamar a API GraphQL (`add_api`) e usar um de seus métodos integrados (`addDynamoDbDataSource`) para fazer a associação entre a tabela e a API GraphQL. Os argumentos são o nome desse link que existirá no AWS AppSync console (`data_source_name_in_console`neste exemplo) e o método da tabela (`add_ddb_table`). Mais informações sobre esse tópico serão reveladas na próxima seção, quando você começar a criar resolvedores.

   Existem métodos alternativos para vincular uma fonte de dados. Tecnicamente, você pode adicionar itens da `api` à lista de propriedades na função de tabela. Por exemplo, aqui está o trecho da etapa 3, mas com propriedades da `api` contendo uma API GraphQL:

   ```
   const add_api = new appsync.GraphqlApi(this, 'API_ID', {
     ...
   });
   
   const add_ddb_table = new dynamodb.Table(this, 'Table_ID', {
   
    ...
   
     api: add_api
   });
   ```

   Como alternativa, você pode chamar a estrutura do `GraphqlApi` separadamente:

   ```
   const add_api = new appsync.GraphqlApi(this, 'API_ID', {
     ...
   });
   
   const add_ddb_table = new dynamodb.Table(this, 'Table_ID', {
     ...
   });
   
   const link_data_source = add_api.addDynamoDbDataSource('data_source_name_in_console', add_ddb_table);
   ```

   Recomendamos criar a associação somente nas propriedades da função. Caso contrário, você precisará vincular sua função de resolução à fonte de dados manualmente no AWS AppSync console (se quiser continuar usando o valor do console`data_source_name_in_console`) ou criar uma associação separada na função com outro nome, como`data_source_name_in_console_2`. Isso se deve às limitações na forma como as propriedades processam as informações.
**nota**  
Você precisará reimplantar a aplicação para conferir as alterações.

------

### Política de confiança do IAM
<a name="iam-trust-policy"></a>

Se você estiver usando uma função do IAM existente para sua fonte de dados, precisará conceder a essa função as permissões apropriadas para realizar operações em seu AWS recurso, como `PutItem` em uma tabela do Amazon DynamoDB. Você também precisa modificar a política de confiança dessa função para permitir seu uso AWS AppSync para acesso a recursos, conforme mostrado no exemplo de política a seguir:

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

****  

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

------

Você também pode adicionar condições à sua política de confiança para limitar o acesso à fonte de dados, conforme desejado. Atualmente, as chaves `SourceArn` e `SourceAccount` podem ser usadas nessas condições. Por exemplo, a política a seguir limita o acesso à sua fonte de dados na conta `123456789012`:

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "appsync.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "123456789012"
        }
      }
    }
  ]
}
```

------

Como alternativa, é possível restringir o acesso de uma API específica a uma fonte de dados, por exemplo, `abcdefghijklmnopq`, usando a seguinte política:

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "appsync.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "ArnEquals": {
          "aws:SourceArn": "arn:aws:appsync:us-west-2:123456789012:apis/abcdefghijklmnopq"
        }
      }
    }
  ]
}
```

------

Você pode limitar o acesso a todos AWS AppSync APIs de uma região específica, por exemplo`us-east-1`, usando a seguinte política:

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "appsync.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "ArnEquals": {
          "aws:SourceArn": "arn:aws:appsync:us-east-1:123456789012:apis/*"
        }
      }
    }
  ]
}
```

------

Na próxima seção ([Configurar os resolvedores](https://docs.aws.amazon.com//appsync/latest/devguide/resolver-config-overview.html)), vamos adicionar nossa lógica de negócios do resolvedor e anexá-la aos campos em nosso esquema para processar os dados em nossa fonte de dados.

Para obter mais informações, consulte [Modificando um perfil](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_roles_manage_modify.html) no *Guia do usuário do IAM*.

Para obter mais informações sobre o acesso entre contas de AWS Lambda resolvedores para AWS AppSync, consulte [Criação de resolvedores entre contas AWS Lambda](https://aws.amazon.com/blogs/mobile/appsync-lambda-cross-account/) para. AWS AppSync

# Configuração de resolvedores no AWS AppSync
<a name="resolver-config-overview"></a>

Nas seções anteriores, você aprendeu a criar o esquema e a fonte de dados do GraphQL e, em seguida, vinculá-los no serviço AWS AppSync. No esquema, você pode ter estabelecido um ou mais campos (operações) na consulta e na mutação. Embora o esquema descrevesse os tipos de dado que as operações solicitariam da fonte de dados, ele nunca implementou o modo como essas operações se comportariam em relação aos dados. 

O comportamento de uma operação é sempre implementado no resolvedor, que será vinculado ao campo que executa a operação. Para obter mais informações sobre como os resolvedores funcionam em geral, consulte a página [Resolvedores](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-components.html).

Em AWS AppSync, o resolvedor é vinculado a um runtime, que é o ambiente no qual o resolvedor é executado. Os runtimes determinam a linguagem na qual o resolvedor será gravado. Atualmente, há dois runtimes compatíveis: APPSYNC\$1JS (JavaScript) e Apache Velocity Template Language (VTL). 

Ao implementar resolvedores, eles seguem uma estrutura geral:
+ **Etapa Anterior**: quando uma solicitação é feita pelo cliente, os resolvedores dos campos do esquema que estão sendo usados (normalmente consultas, mutações e assinaturas) recebem os dados da solicitação. O resolvedor começará a processar os dados da solicitação com um manipulador de etapas anteriores, o que permite que algumas operações de pré-processamento sejam executadas antes que os dados passem pelo resolvedor.
+ **Função(ões)**: Após a execução da etapa anterior, a solicitação é passada para a lista de funções. A primeira função na lista será executada na fonte de dados. Uma função é um subconjunto do código do resolvedor contendo seu próprio manipulador de solicitações e respostas. Um manipulador de solicitações pegará os dados da solicitação e executará operações na fonte de dados. O manipulador de respostas processará a resposta da fonte de dados antes de passá-la de volta para a lista. Se houver mais de uma função, os dados da solicitação serão enviados para a próxima função a ser executada na lista. As funções na lista serão executadas na ordem definida pelo desenvolvedor. Depois que todas as funções forem executadas, o resultado final será passado para a etapa posterior.
+ **Etapa Posterior**: A etapa Posterior é uma função do manipulador que permite realizar algumas operações finais na resposta da função final antes de passá-la para a resposta do GraphQL.

Esse fluxo é um exemplo de um resolvedor de pipeline. Os resolvedores de pipeline são compatíveis em ambos os runtimes. No entanto, essa é uma explicação simplificada do que os resolvedores de pipeline podem fazer. Além disso, estamos descrevendo apenas uma configuração possível do resolvedor. Para obter mais informações sobre as configurações de resolvedor compatíveis, consulte a [Visão geral dos resolvedores do JavaScript](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html) para APPSYNC\$1JS ou a [Visão geral do modelo de mapeamento do resolvedor](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-overview.html) para VTL.

Como você pode ver, os resolvedores são modulares. Para que os componentes do resolvedor funcionem corretamente, eles devem ser capazes de examinar o estado da execução por meio de outros componentes. Na seção [Resolvedores](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-components.html), você sabe que cada componente no resolvedor pode receber informações essenciais sobre o estado da execução como um conjunto de argumentos (`args`, `context` etc.). Em AWS AppSync, isso é tratado estritamente pelo `context`. Trata-se de um contêiner para as informações sobre o campo que está sendo resolvido. Isso pode incluir tudo, desde argumentos passados, resultados, dados de autorização, dados de cabeçalho etc. Para obter mais informações sobre o contexto, consulte [Referência do objeto de contexto do resolvedor](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html) para APPSYNC\$1JS ou a [Referência de contexto do modelo de mapeamento do resolvedor](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference.html) para VTL.

O contexto não é a única ferramenta que você pode usar para implementar seu resolvedor. O AWS AppSync suporta uma ampla variedade de utilitários para geração de valor, tratamento de erros, análise, conversão etc. Você pode ver uma lista de utilitários [aqui](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html) para APPSYNC\$1JS ou [aqui](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference.html) para VTL.

Nas seções a seguir, você vai aprender a configurar resolvedores na API do GraphQL.

**Topics**
+ [Criação de consultas básicas () JavaScript](configuring-resolvers-js.md)
+ [Criação de consultas básicas (VTL)](configuring-resolvers.md)

# Criação de consultas básicas () JavaScript
<a name="configuring-resolvers-js"></a>

Os resolvedores do GraphQL conectam os campos em um esquema de tipo a uma fonte de dados. Os resolvedores são o mecanismo pelo qual as solicitações são atendidas.

Resolvedores em AWS AppSync uso JavaScript para converter uma expressão GraphQL em um formato que a fonte de dados possa usar. Como alternativa, os modelos de mapeamento podem ser escritos em [Apache VTL (Velocity Template Language)](https://velocity.apache.org/engine/2.0/vtl-reference.html) para converter uma expressão de GraphQL em um formato que a fonte de dados possa usar.

Esta seção descreve como configurar resolvedores usando o. JavaScript A seção [Tutoriais do Resolver (JavaScript)](https://docs.aws.amazon.com/appsync/latest/devguide/tutorials-js.html) fornece tutoriais detalhados sobre como implementar resolvedores usando. JavaScript A seção [Referência do Resolvedor (JavaScript)](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html) fornece uma explicação das operações do utilitário que podem ser usadas com JavaScript resolvedores.

Recomendamos seguir este guia antes de tentar usar qualquer um dos tutoriais mencionados acima.

Nesta seção, mostraremos como criar e configurar resolvedores de consultas e mutações.

**nota**  
Este guia pressupõe que você tenha criado seu esquema e tenha pelo menos uma consulta ou mutação. Se você estiver procurando por assinaturas (dados em tempo real), consulte [este guia](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-data.html).

Nesta seção, abordaremos algumas etapas gerais para configurar resolvedores e mostraremos um exemplo com o esquema abaixo:

```
// schema.graphql file

input CreatePostInput {
  title: String
  date: AWSDateTime
}

type Post {
  id: ID!
  title: String
  date: AWSDateTime
}

type Mutation {
  createPost(input: CreatePostInput!): Post
}

type Query {
  getPost: [Post]
}
```

## Criação de resolvedores de consultas básicos
<a name="create-basic-query-resolver-js"></a>

Esta seção mostrará como criar um resolvedor de consultas básico.

------
#### [ Console ]

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

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

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

1. Insira os detalhes do esquema e da fonte de dados. Consulte as seções [Criar seu esquema](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html) e [Anexar uma fonte de dados](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html) para obter mais informações.

1. Ao lado do editor de **esquemas**, há uma janela chamada **Resolvedores**. Essa caixa contém uma lista dos tipos e campos conforme definido na janela **Esquema**. É possível anexar resolvedores aos campos. Você provavelmente estará anexando resolvedores às suas operações de campo. Nesta seção, veremos configurações de consultas simples. Em **Tipo de consulta**, escolha **Anexar** ao lado do campo da sua consulta.

1. Na página **Anexar resolvedor**, em **Tipo de resolvedor**, você pode escolher entre resolvedores de pipeline ou de unidade. Para obter mais informações sobre esses tipos de regra, consulte [Resolvedores](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-components.html). Este guia fará uso de `pipeline resolvers`.
**dica**  
Ao criar resolvedores de pipeline, suas fontes de dados serão anexadas às funções do pipeline. As funções são geradas depois que você cria o próprio resolvedor de pipeline, e é por isso que não há opção de configurá-lo nesta página. Se você estiver usando um resolvedor de unidades, a fonte de dados estará vinculada diretamente ao resolvedor, portanto, você o definiria nesta página.

   Para o **tempo de execução do Resolver**, escolha `APPSYNC_JS` ativar o JavaScript tempo de execução.

1. Você pode ativar o [armazenamento em cache](https://docs.aws.amazon.com/appsync/latest/devguide/enabling-caching.html) dessa API. Recomendamos desativar esse atributo por enquanto. Selecione **Criar**.

1. Na página **Editar resolvedor**, há um editor de código chamado **Código do resolvedor** que permite implementar a lógica para o manipulador e a resposta do resolvedor (etapas anterior e posterior). Para obter mais informações, consulte a [visão geral dos JavaScript resolvedores](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html). 
**nota**  
Em nosso exemplo, vamos deixar a solicitação em branco e a resposta definida para retornar o resultado da última fonte de dados do [contexto](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html):  

   ```
   import {util} from '@aws-appsync/utils';
   
   export function request(ctx) {
       return {};
   }
   
   export function response(ctx) {
       return ctx.prev.result;
   }
   ```

   Abaixo dessa seção, há uma tabela chamada **Funções**. As funções permitem que você implemente códigos que possam ser reutilizados em vários resolvedores. Em vez de reescrever ou copiar sempre o código, você pode armazenar o código-fonte como uma função a ser adicionada a um resolvedor sempre que precisar. 

   As funções compõem a maior parte da lista de operações de um pipeline. Ao usar várias funções em um resolvedor, você define a ordem das funções, e elas serão executadas nessa ordem sequencialmente. Elas são executadas depois da função de solicitação e antes do início da função de resposta.

   Para adicionar uma nova função, em **Funções**, escolha **Adicionar função** e, em seguida, **Criar nova função**. Como alternativa, pode haver um botão **Criar função** para escolher.

   1. Escolha uma fonte de dados. Essa será a fonte de dados em que o resolvedor vai atuar.
**nota**  
Em nosso exemplo, estamos anexando um resolvedor para `getPost`, que recupera um objeto `Post` pelo `id`. Vamos supor que já tenhamos configurado uma tabela do DynamoDB para esse esquema. Sua chave de partição está vazia e definida como `id`.

   1. Insira um `Function name`.

   1. Em **Código da função**, você precisará implementar o comportamento da função. Isso pode ser confuso, mas cada função terá seu próprio manipulador local de solicitações e respostas. A solicitação é executada e, em seguida, a invocação da fonte de dados é feita para lidar com a solicitação e, em seguida, a resposta da fonte de dados é processada pelo manipulador. O resultado é armazenado no objeto do [contexto](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html). Depois disso, a próxima função na lista será executada ou transmitida para o manipulador de resposta da etapa posterior, se for a última. 
**nota**  
Em nosso exemplo, estamos anexando um resolvedor ao `getPost`, que obtém uma lista de objetos `Post` da fonte de dados. Nossa função de solicitação solicitará os dados da nossa tabela, a tabela passará sua resposta para o contexto (ctx) e, em seguida, a resposta retornará o resultado no contexto. AWS AppSync A força da está em sua interconexão com outros serviços. AWS Como estamos usando o DynamoDB, temos [um conjunto de operações](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html) para simplificar processos como esses. Também temos alguns exemplos padronizados para outros tipos de fontes de dados.  
Nosso código será semelhante a este:  

      ```
      import { util } from '@aws-appsync/utils';
      
      /**
       * Performs a scan on the dynamodb data source
       */
      export function request(ctx) {
        return { operation: 'Scan' };
      }
      
      /**
       * return a list of scanned post items
       */
      export function response(ctx) {
        return ctx.result.items;
      }
      ```
Nesta etapa, adicionamos duas funções:  
`request`: o manipulador de solicitações executa a operação de recuperação na fonte de dados. O argumento contém o objeto de contexto (`ctx`) ou alguns dados que estão disponíveis para todos os resolvedores que executam uma operação específica. Por exemplo, ele pode conter dados de autorização, os nomes dos campos que estão sendo resolvidos etc. A instrução return executa uma operação de [https://docs.aws.amazon.com//appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-scan](https://docs.aws.amazon.com//appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-scan) (confira exemplos [aqui](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html)). Como estamos trabalhando com o DynamoDB, podemos usar algumas das operações desse serviço. A verificação executa uma busca básica de todos os itens em nossa tabela. O resultado dessa operação é armazenado no objeto de contexto como um contêiner de `result` antes de ser transmitido ao manipulador de respostas. A `request` é executada antes da resposta no pipeline.
`response`: o manipulador de respostas que retorna o resultado da `request`. O argumento é o objeto de contexto atualizado e a instrução de retorno é `ctx.prev.result`. Neste ponto do guia, é possível que você não conheça esse valor. `ctx` refere-se ao objeto de contexto, e `prev` refere-se à operação anterior no pipeline, que era nossa `request`. O `result` contém os resultados do resolvedor à medida que ele se move pelo pipeline. Se você juntar tudo isso, `ctx.prev.result` está retornando o resultado da última operação realizada, que foi o manipulador da solicitação.

   1. Depois de concluir, escolha **Criar**.

1. De volta à tela do resolvedor, em **Funções**, escolha o menu suspenso **Adicionar função** e inclua sua função na sua lista.

1. Escolha **Salvar** para atualizar o resolvedor.

------
#### [ CLI ]

**Para adicionar sua função**
+ Crie uma função para seu resolvedor de pipeline usando o comando `[create-function](https://docs.aws.amazon.com/cli/latest/reference/appsync/create-function.html)`.

  Você precisará inserir alguns parâmetros para esse comando específico:

  1. O `api-id` da sua API.

  1. O `name` da função no AWS AppSync console.

  1. O `data-source-name`, ou o nome da fonte de dados que a função usará. Ele já deve ter sido criado e vinculado à sua API do GraphQL no serviço do AWS AppSync .

  1. O`runtime`, ou ambiente e idioma da função. Para JavaScript, o nome deve ser`APPSYNC_JS`, e o tempo de execução,`1.0.0`.

  1. O `code`, ou manipuladores de solicitações e respostas de sua função. Embora você possa digitá-lo manualmente, é muito mais fácil adicioná-lo a um arquivo .txt (ou formato similar) e depois transmiti-lo como argumento. 
**nota**  
Nosso código de consulta estará em um arquivo transmitido como argumento:  

     ```
     import { util } from '@aws-appsync/utils';
     
     /**
      * Performs a scan on the dynamodb data source
      */
     export function request(ctx) {
       return { operation: 'Scan' };
     }
     
     /**
      * return a list of scanned post items
      */
     export function response(ctx) {
       return ctx.result.items;
     }
     ```

  Veja um exemplo de comando:

  ```
  aws appsync create-function \
  --api-id abcdefghijklmnopqrstuvwxyz \
  --name get_posts_func_1 \
  --data-source-name table-for-posts \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
  --code file://~/path/to/file/{filename}.{fileType}
  ```

  Uma saída será retornada na CLI. Veja um exemplo abaixo:

  ```
  {
      "functionConfiguration": {
          "functionId": "ejglgvmcabdn7lx75ref4qeig4",
          "functionArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/functions/ejglgvmcabdn7lx75ref4qeig4",
          "name": "get_posts_func_1",
          "dataSourceName": "table-for-posts",
          "maxBatchSize": 0,
          "runtime": {
              "name": "APPSYNC_JS",
              "runtimeVersion": "1.0.0"
          },
          "code": "Code output goes here"
      }
  }
  ```
**nota**  
Certifique-se de gravar o `functionId` em algum lugar, pois isso será usado para anexar a função ao solucionados.

**Criar seu resolvedor**
+ Crie uma função de pipeline para `Query` executando o comando `[create-resolver](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html)`.

  Você precisará inserir alguns parâmetros para esse comando específico:

  1. O `api-id` da sua API.

  1. O `type-name`, ou o tipo de objeto especial em seu esquema (consulta, mutação, assinatura).

  1. O `field-name` ou a operação do campo no tipo de objeto especial a ser anexado ao resolvedor.

  1. O `kind`, que especifica um resolvedor de unidade ou pipeline. Defina como `PIPELINE` para ativar as funções do pipeline.

  1. A `pipeline-config`, ou as funções a serem anexadas ao resolvedor. É preciso saber os valores de `functionId` de suas funções. A ordem da listagem é importante.

  1. O`runtime`, que foi `APPSYNC_JS` (JavaScript). Atualmente o `runtimeVersion` é`1.0.0`.

  1. O `code`, que contém os manipuladores das etapas anterior e posterior.
**nota**  
Nosso código de consulta estará em um arquivo transmitido como argumento:  

     ```
     import { util } from '@aws-appsync/utils';
     
     /**
      * Sends a request to `put` an item in the DynamoDB data source
      */
     export function request(ctx) {
       const { id, ...values } = ctx.args;
       return {
         operation: 'PutItem',
         key: util.dynamodb.toMapValues({ id }),
         attributeValues: util.dynamodb.toMapValues(values),
       };
     }
     
     /**
      * returns the result of the `put` operation
      */
     export function response(ctx) {
       return ctx.result;
     }
     ```

  Veja um exemplo de comando:

  ```
  aws appsync create-resolver \
  --api-id abcdefghijklmnopqrstuvwxyz \
  --type-name Query \
  --field-name getPost \
  --kind PIPELINE \
  --pipeline-config functions=ejglgvmcabdn7lx75ref4qeig4 \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
  --code file:///path/to/file/{filename}.{fileType}
  ```

  Uma saída será retornada na CLI. Veja um exemplo abaixo:

  ```
  {
      "resolver": {
          "typeName": "Mutation",
          "fieldName": "getPost",
          "resolverArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Mutation/resolvers/getPost",
          "kind": "PIPELINE",
          "pipelineConfig": {
              "functions": [
                  "ejglgvmcabdn7lx75ref4qeig4"
              ]
          },
          "maxBatchSize": 0,
          "runtime": {
              "name": "APPSYNC_JS",
              "runtimeVersion": "1.0.0"
          },
          "code": "Code output goes here"
      }
  }
  ```

------
#### [ CDK ]

**dica**  
[Antes de usar o CDK, recomendamos revisar a [documentação oficial](https://docs.aws.amazon.com/cdk/v2/guide/home.html) do CDK junto com AWS AppSync a referência do CDK.](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
As etapas listadas abaixo mostram apenas um exemplo geral do trecho usado para adicionar um recurso específico. Isso **não** é uma solução funcional para seu código de produção. Também presumimos que você já tenha uma aplicação em funcionamento.

Uma aplicação básica precisará do seguinte:

1. Diretivas de importação de serviços

1. Código do esquema

1. Gerador de fontes de dados

1. Código da função

1. Código do resolvedor

Nas seções [Projetar seu esquema](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html) e [Anexar uma fonte de dados](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html), sabemos que o arquivo de pilha incluirá as diretivas de importação do formulário:

```
import * as x from 'x'; # import wildcard as the 'x' keyword from 'x-service'
import {a, b, ...} from 'c'; # import {specific constructs} from 'c-service'
```

**nota**  
Nas seções anteriores, declaramos apenas como importar AWS AppSync construções. Em código real, você precisará importar mais serviços apenas para executar a aplicação. Em nosso exemplo, se criássemos um aplicativo CDK muito simples, importaríamos pelo menos o AWS AppSync serviço junto com nossa fonte de dados, que era uma tabela do DynamoDB. Também precisaríamos importar algumas estruturas adicionais para implantar a aplicação:  

```
import * as cdk from 'aws-cdk-lib';
import * as appsync from 'aws-cdk-lib/aws-appsync';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import { Construct } from 'constructs';
```
Para resumir cada uma delas:  
`import * as cdk from 'aws-cdk-lib';`: isso permite que você defina a aplicação e as estruturas do CDK, como a pilha. Ela também contém algumas funções utilitárias relevantes para nosso aplicativo, como a manipulação de metadados. Se você já conhece essa diretiva de importação, mas não sabe por que a biblioteca principal do CDK não está sendo usada aqui, consulte a página de [migração](https://docs.aws.amazon.com/cdk/v2/guide/migrating-v2.html).
`import * as appsync from 'aws-cdk-lib/aws-appsync';`: isso importa o [serviço do AWS AppSync](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html).
`import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';`: isso importa o [serviço do DynamoDB](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_dynamodb-readme.html).
`import { Construct } from 'constructs';`: precisamos disso para definir a [estrutura](https://docs.aws.amazon.com/cdk/v2/guide/constructs.html)-raiz.

O tipo de importação depende dos serviços que você está chamando. Recomendamos consultar a documentação do CDK para ver exemplos. O esquema na parte superior da página será um arquivo separado na sua aplicação do CDK como um arquivo `.graphql`. No arquivo de pilha, podemos associá-lo a um novo GraphQL usando este formato:

```
const add_api = new appsync.GraphqlApi(this, 'graphQL-example', {
  name: 'my-first-api',
  schema: appsync.SchemaFile.fromAsset(path.join(__dirname, 'schema.graphql')),
});
```

**nota**  
No escopo do `add_api`, vamos adicionar uma nova API GraphQL usando a `new` palavra-chave seguida por `appsync.GraphqlApi(scope: Construct, id: string , props: GraphqlApiProps)`. Nosso escopo é `this`, o ID do CFN é `graphQL-example`, e nossas propriedades são `my-first-api` (nome da API no console) e `schema.graphql` (o caminho absoluto para o arquivo do esquema).

Para incluir uma fonte de dados, primeiro você precisa adicionar sua fonte de dados à pilha. Em seguida, associá-la à API GraphQL usando o método específico da fonte. A associação acontecerá quando seu resolvedor funcionar. Enquanto isso, vamos usar um exemplo criando a tabela do DynamoDB usando `dynamodb.Table`:

```
const add_ddb_table = new dynamodb.Table(this, 'posts-table', {
  partitionKey: {
    name: 'id',
    type: dynamodb.AttributeType.STRING,
  },
});
```

**nota**  
Se usássemos isso em nosso exemplo, adicionaríamos uma nova tabela do DynamoDB com o ID do CFN e uma chave de partição `posts-table` do `id (S)`.

Em seguida, precisamos implementar nosso resolvedor no arquivo de pilha. Veja a seguir um exemplo de uma consulta simples que verifica todos os itens em uma tabela do DynamoDB:

```
const add_func = new appsync.AppsyncFunction(this, 'func-get-posts', {
  name: 'get_posts_func_1',
  add_api,
  dataSource: add_api.addDynamoDbDataSource('table-for-posts', add_ddb_table),
  code: appsync.Code.fromInline(`
      export function request(ctx) {
        return { operation: 'Scan' };
      }

      export function response(ctx) {
        return ctx.result.items;
      }
  `),
  runtime: appsync.FunctionRuntime.JS_1_0_0,
});

new appsync.Resolver(this, 'pipeline-resolver-get-posts', {
  add_api,
  typeName: 'Query',
  fieldName: 'getPost',
  code: appsync.Code.fromInline(`
      export function request(ctx) {
        return {};
      }

      export function response(ctx) {
        return ctx.prev.result;
      }
 `),
  runtime: appsync.FunctionRuntime.JS_1_0_0,
  pipelineConfig: [add_func],
});
```

**nota**  
Primeiro, criamos uma função chamada `add_func`. Essa ordem de criação pode parecer um pouco contraintuitiva, mas você precisa criar as funções em seu resolvedor de pipeline antes de criar o próprio resolvedor. Uma função segue o formato:  

```
AppsyncFunction(scope: Construct, id: string, props: AppsyncFunctionProps)
```
Nosso escopo era `this`, nosso ID de CFN, `func-get-posts`, e nossas propriedades continham os detalhes reais da função. Dentro das propriedades, incluímos:  
A `name` da função que estará presente no AWS AppSync console (`get_posts_func_1`).
A API GraphQL que criamos anteriormente (`add_api`).
A fonte de dados; esse é o ponto em que vinculamos a fonte de dados ao valor da API GraphQL e a anexamos à função. Pegamos a tabela que criamos (`add_ddb_table`) e a anexamos à API GraphQL (`add_api`) usando um dos métodos `GraphqlApi` ([https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.GraphqlApi.html#addwbrdynamowbrdbwbrdatawbrsourceid-table-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.GraphqlApi.html#addwbrdynamowbrdbwbrdatawbrsourceid-table-options)). O valor do ID (`table-for-posts`) é o nome da fonte de dados no console do AWS AppSync . Para obter a lista dos métodos específicos da fonte, consulte as seguintes páginas:  
[ DynamoDbDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.DynamoDbDataSource.html) 
 [ EventBridgeDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.EventBridgeDataSource.html) 
 [ HttpDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.HttpDataSource.html) 
 [ LambdaDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.LambdaDataSource.html) 
 [ NoneDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.NoneDataSource.html) 
 [ OpenSearchDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.OpenSearchDataSource.html) 
 [ RdsDataSource ](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync.RdsDataSource.html) 
O código contém os manipuladores de solicitações e respostas da nossa função, que são uma simples digitalização e retorno.
O runtime especifica que queremos usar a versão 1.0.0 do runtime do APPSYNC\$1JS. Observe que atualmente essa é a única versão disponível do APPSYNC\$1JS.
Em seguida, precisamos anexar a função ao resolvedor de pipeline. Criamos nosso resolvedor usando o formulário:  

```
Resolver(scope: Construct, id: string, props: ResolverProps)
```
Nosso escopo era `this`, nosso ID de CFN, `pipeline-resolver-get-posts`, e nossas propriedades continham os detalhes reais da função. Dentro das propriedades, incluímos:  
A API GraphQL que criamos anteriormente (`add_api`).
O nome do tipo de objeto especial; essa é uma operação de consulta, então só adicionamos o valor da `Query`.
O nome do campo (`getPost`) é aquele no esquema abaixo do tipo de `Query`.
O código contém seus manipuladores de antes e depois. Nosso exemplo só vão retornar os resultados que estavam no contexto depois que a função tiver executado a operação.
O runtime especifica que queremos usar a versão 1.0.0 do runtime do APPSYNC\$1JS. Observe que atualmente essa é a única versão disponível do APPSYNC\$1JS.
A configuração do pipeline contém a referência à função que criamos (`add_func`).

------

Para resumir o que aconteceu neste exemplo, você viu uma AWS AppSync função que implementou um manipulador de solicitações e respostas. A função foi responsável por interagir com sua fonte de dados. O manipulador da solicitação enviou uma `Scan` operação para AWS AppSync, instruindo-a sobre qual operação realizar na sua fonte de dados do DynamoDB. O manipulador de respostas retornou a lista de itens (`ctx.result.items`). A lista de itens foi então mapeada automaticamente para o tipo `Post` GraphQL. 

## Criar resolvedores básicos de mutação
<a name="creating-basic-mutation-resolvers-js"></a>

Esta seção mostrará como criar um resolvedor de mutação básico.

------
#### [ Console ]

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

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

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

1. Na seção **Resolvedores** e no tipo de **mutação**, escolha **Anexar** ao lado do seu campo.
**nota**  
Em nosso exemplo, estamos anexando um resolvedor para `createPost`, que recupera um objeto `Post` para nossa tabela. Vamos supor que estamos usando a mesma tabela do DynamoDB da última seção. Sua chave de partição está vazia e definida como `id`.

1. Na página **Anexar resolvedor**, em **Tipo de resolvedor**, escolha `pipeline resolvers`. Como lembrete, você pode encontrar mais informações sobre resolvedores [aqui](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-components.html). Para o **tempo de execução do Resolver**, escolha `APPSYNC_JS` ativar o JavaScript tempo de execução.

1. Você pode ativar o [armazenamento em cache](https://docs.aws.amazon.com/appsync/latest/devguide/enabling-caching.html) dessa API. Recomendamos desativar esse atributo por enquanto. Selecione **Criar**.

1. Escolha **Adicionar função** e, em seguida, **Criar nova função**. Como alternativa, pode haver um botão **Criar função** para escolher.

   1. Selecione sua fonte de dados. Essa deve ser a fonte cujos dados você manipulará com a mutação.

   1. Insira um `Function name`.

   1. Em **Código da função**, você precisará implementar o comportamento da função. Isso é uma mutação, portanto, o ideal é que a solicitação realize alguma operação de mudança de estado na fonte de dados invocada. O resultado será processado pela função de resposta.
**nota**  
O `createPost` adiciona ou “insere” um novo `Post` na tabela com nossos parâmetros como dados. Isso pode ser semelhante a:   

      ```
      import { util } from '@aws-appsync/utils';
      
      /**
       * Sends a request to `put` an item in the DynamoDB data source
       */
      export function request(ctx) {
        return {
          operation: 'PutItem',
          key: util.dynamodb.toMapValues({id: util.autoId()}),
          attributeValues: util.dynamodb.toMapValues(ctx.args.input),
        };
      }
      
      /**
       * returns the result of the `put` operation
       */
      export function response(ctx) {
        return ctx.result;
      }
      ```
Nesta etapa, adicionamos as funções `request` e `response`:  
`request`: o manipulador da solicitação aceita o contexto como argumento. A instrução return do manipulador de solicitações executa um comando [https://docs.aws.amazon.com//appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-putitem](https://docs.aws.amazon.com//appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-putitem), que é uma operação integrada do DynamoDB (confira alguns exemplos [neste link](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/getting-started-step-2.html) ou [aqui](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithItems.html#WorkingWithItems.WritingData)). O comando `PutItem` adiciona um objeto `Post` à nossa tabela do DynamoDB considerando o valor `key` da partição (gerado automaticamente por `util.autoid()`) e `attributes` a partir da entrada do argumento de contexto (esses são os valores que vamos transmitir em nossa solicitação). A `key` é o `id`, e os `attributes` são os argumentos de campo `date` e `title`. Ambos são pré-formatados por meio do auxiliar [https://docs.aws.amazon.com//appsync/latest/devguide/dynamodb-helpers-in-util-dynamodb-js.html#utility-helpers-in-toMap-js](https://docs.aws.amazon.com//appsync/latest/devguide/dynamodb-helpers-in-util-dynamodb-js.html#utility-helpers-in-toMap-js) para trabalhar com a tabela do DynamoDB.
`response`: a resposta aceita o contexto atualizado e retorna o resultado do manipulador da solicitação.

   1. Depois de concluir, escolha **Criar**.

1. De volta à tela do resolvedor, em **Funções**, escolha o menu suspenso **Adicionar função** e inclua sua função na sua lista.

1. Escolha **Salvar** para atualizar o resolvedor.

------
#### [ CLI ]

**Para adicionar sua função**
+ Crie uma função para seu resolvedor de pipeline usando o comando `[create-function](https://docs.aws.amazon.com/cli/latest/reference/appsync/create-function.html)`.

  Você precisará inserir alguns parâmetros para esse comando específico:

  1. O `api-id` da sua API.

  1. O `name` da função no AWS AppSync console.

  1. O `data-source-name`, ou o nome da fonte de dados que a função usará. Ele já deve ter sido criado e vinculado à sua API do GraphQL no serviço do AWS AppSync .

  1. O`runtime`, ou ambiente e idioma da função. Para JavaScript, o nome deve ser`APPSYNC_JS`, e o tempo de execução,`1.0.0`.

  1. O `code`, ou manipuladores de solicitações e respostas de sua função. Embora você possa digitá-lo manualmente, é muito mais fácil adicioná-lo a um arquivo .txt (ou formato similar) e depois transmiti-lo como argumento. 
**nota**  
Nosso código de consulta estará em um arquivo transmitido como argumento:  

     ```
     import { util } from '@aws-appsync/utils';
     
     /**
      * Sends a request to `put` an item in the DynamoDB data source
      */
     export function request(ctx) {
       return {
         operation: 'PutItem',
         key: util.dynamodb.toMapValues({id: util.autoId()}),
         attributeValues: util.dynamodb.toMapValues(ctx.args.input),
       };
     }
     
     /**
      * returns the result of the `put` operation
      */
     export function response(ctx) {
       return ctx.result;
     }
     ```

  Veja um exemplo de comando:

  ```
  aws appsync create-function \
  --api-id abcdefghijklmnopqrstuvwxyz \
  --name add_posts_func_1 \
  --data-source-name table-for-posts \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
  --code file:///path/to/file/{filename}.{fileType}
  ```

  Uma saída será retornada na CLI. Veja um exemplo abaixo:

  ```
  {
      "functionConfiguration": {
          "functionId": "vulcmbfcxffiram63psb4dduoa",
          "functionArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/functions/vulcmbfcxffiram63psb4dduoa",
          "name": "add_posts_func_1",
          "dataSourceName": "table-for-posts",
          "maxBatchSize": 0,
          "runtime": {
              "name": "APPSYNC_JS",
              "runtimeVersion": "1.0.0"
          },
          "code": "Code output foes here"
      }
  }
  ```
**nota**  
Certifique-se de gravar o `functionId` em algum lugar, pois isso será usado para anexar a função ao solucionados.

**Criar seu resolvedor**
+ Crie uma função de pipeline para `Mutation` executando o comando `[create-resolver](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html)`.

  Você precisará inserir alguns parâmetros para esse comando específico:

  1. O `api-id` da sua API.

  1. O `type-name`, ou o tipo de objeto especial em seu esquema (consulta, mutação, assinatura).

  1. O `field-name` ou a operação do campo no tipo de objeto especial a ser anexado ao resolvedor.

  1. O `kind`, que especifica um resolvedor de unidade ou pipeline. Defina como `PIPELINE` para ativar as funções do pipeline.

  1. A `pipeline-config`, ou as funções a serem anexadas ao resolvedor. É preciso saber os valores de `functionId` de suas funções. A ordem da listagem é importante.

  1. O`runtime`, que foi `APPSYNC_JS` (JavaScript). Atualmente o `runtimeVersion` é`1.0.0`.

  1. O `code`, que contém os manipuladores das etapas anterior e posterior.
**nota**  
Nosso código de consulta estará em um arquivo transmitido como argumento:  

     ```
     import { util } from '@aws-appsync/utils';
     
     /**
      * Sends a request to `put` an item in the DynamoDB data source
      */
     export function request(ctx) {
       const { id, ...values } = ctx.args;
       return {
         operation: 'PutItem',
         key: util.dynamodb.toMapValues({ id }),
         attributeValues: util.dynamodb.toMapValues(values),
       };
     }
     
     /**
      * returns the result of the `put` operation
      */
     export function response(ctx) {
       return ctx.result;
     }
     ```

  Veja um exemplo de comando:

  ```
  aws appsync create-resolver \
  --api-id abcdefghijklmnopqrstuvwxyz \
  --type-name Mutation \
  --field-name createPost \
  --kind PIPELINE \
  --pipeline-config functions=vulcmbfcxffiram63psb4dduoa \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0 \
  --code file:///path/to/file/{filename}.{fileType}
  ```

  Uma saída será retornada na CLI. Veja um exemplo abaixo:

  ```
  {
      "resolver": {
          "typeName": "Mutation",
          "fieldName": "createPost",
          "resolverArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Mutation/resolvers/createPost",
          "kind": "PIPELINE",
          "pipelineConfig": {
              "functions": [
                  "vulcmbfcxffiram63psb4dduoa"
              ]
          },
          "maxBatchSize": 0,
          "runtime": {
              "name": "APPSYNC_JS",
              "runtimeVersion": "1.0.0"
          },
          "code": "Code output goes here"
      }
  }
  ```

------
#### [ CDK ]

**dica**  
[Antes de usar o CDK, recomendamos revisar a [documentação oficial](https://docs.aws.amazon.com/cdk/v2/guide/home.html) do CDK junto com AWS AppSync a referência do CDK.](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
As etapas listadas abaixo mostram apenas um exemplo geral do trecho usado para adicionar um recurso específico. Isso **não** é uma solução funcional para seu código de produção. Também presumimos que você já tenha uma aplicação em funcionamento.
+ Para fazer uma mutação, supondo que esteja no mesmo projeto, você pode adicioná-la ao arquivo de pilha como na consulta. Aqui está uma função e um resolvedor modificados para uma mutação que adiciona uma nova `Post` à tabela:

  ```
  const add_func_2 = new appsync.AppsyncFunction(this, 'func-add-post', {
    name: 'add_posts_func_1',
    add_api,
    dataSource: add_api.addDynamoDbDataSource('table-for-posts-2', add_ddb_table),
        code: appsync.Code.fromInline(`
            export function request(ctx) {
              return {
                operation: 'PutItem',
                key: util.dynamodb.toMapValues({id: util.autoId()}),
                attributeValues: util.dynamodb.toMapValues(ctx.args.input),
              };
            }
  
            export function response(ctx) {
              return ctx.result;
            }
        `), 
    runtime: appsync.FunctionRuntime.JS_1_0_0,
  });
  
  new appsync.Resolver(this, 'pipeline-resolver-create-posts', {
    add_api,
    typeName: 'Mutation',
    fieldName: 'createPost',
        code: appsync.Code.fromInline(`
            export function request(ctx) {
              return {};
            }
  
            export function response(ctx) {
              return ctx.prev.result;
            }
        `),
    runtime: appsync.FunctionRuntime.JS_1_0_0,
    pipelineConfig: [add_func_2],
  });
  ```
**nota**  
Como essa mutação e a consulta são estruturadas de forma semelhante, explicaremos apenas as alterações que implementamos para fazer a mutação.   
Na função, alteramos o ID da CFN `func-add-post` e o nome para `add_posts_func_1` para refletir o fato de que estamos adicionando `Posts` à tabela. Na fonte de dados, fizemos uma nova associação à nossa tabela (`add_ddb_table`) no AWS AppSync console `table-for-posts-2` porque o `addDynamoDbDataSource` método exige isso. Lembre-se de que essa nova associação ainda está usando a mesma tabela que criamos anteriormente, mas agora temos duas conexões com ela no AWS AppSync console: uma para a consulta as `table-for-posts` e outra para a mutação as`table-for-posts-2`. O código foi alterado para adicionar uma `Post` gerando o valor do `id` automaticamente e aceitando a entrada de um cliente para o resto dos campos.  
No resolvedor, mudamos o valor do ID para `pipeline-resolver-create-posts` a fim de refletir o fato de que estamos adicionando `Posts` à tabela. Para refletir a mutação no esquema, o nome do tipo mudou para `Mutation`, e o nome para `createPost`. A configuração do pipeline foi definida para nossa nova função de mutação `add_func_2`.

------

Para resumir o que está acontecendo neste exemplo, converte AWS AppSync automaticamente os argumentos definidos no `createPost` campo do seu esquema do GraphQL em operações do DynamoDB. O exemplo armazena registros no DynamoDB usando uma chave do `id`, que é criada automaticamente usando nosso auxiliar `util.autoId()`. Todos os outros campos que você passar para os argumentos de contexto (`ctx.args.input`) de solicitações feitas no AWS AppSync console ou de outra forma serão armazenados como atributos da tabela. Tanto a chave quanto os atributos são mapeados automaticamente para um formato compatível do DynamoDB usando o auxiliar `util.dynamodb.toMapValues(values)`.

AWS AppSync também oferece suporte a fluxos de trabalho de teste e depuração para edição de resolvedores. Use um objeto `context` de simulação para ver o valor do modelo transformado antes da invocá-lo. Uma alternativa é visualizar a execução de solicitação completa de uma fonte de dados de forma interativa ao executar uma consulta. Para obter mais informações, consulte [Resolvers de teste e depuração (JavaScript)](https://docs.aws.amazon.com/appsync/latest/devguide/test-debug-resolvers-js.html) e [Monitoramento e registro](https://docs.aws.amazon.com/appsync/latest/devguide/monitoring.html#aws-appsync-monitoring).

## Resolvedores avançados
<a name="advanced-resolvers-js"></a>

Se você estiver seguindo a seção opcional de paginação em [Projetar seu esquema](designing-your-schema.md#aws-appsync-designing-your-schema), ainda precisará adicionar seu resolvedor à sua solicitação para usar a paginação. Nosso exemplo usou uma paginação de consulta chamada `getPosts` para retornar somente uma parte das coisas solicitadas por vez. O código do nosso resolvedor nesse campo pode ter a seguinte aparência:

```
/**
 * Performs a scan on the dynamodb data source
 */
export function request(ctx) {
  const { limit = 20, nextToken } = ctx.args;
  return { operation: 'Scan', limit, nextToken };
}

/**
 * @returns the result of the `put` operation
 */
export function response(ctx) {
  const { items: posts = [], nextToken } = ctx.result;
  return { posts, nextToken };
}
```

Na solicitação, transmitimos no contexto dela. Nosso `limit` é*20*, o que significa que retornamos até 20 `Posts` na primeira consulta. Nosso cursor do `nextToken` está fixo na primeira entrada da `Post` na fonte de dados. Eles são transmitidos para os argumentos. Em seguida, a solicitação executa uma varredura desde a primeira `Post` até o número limite de varredura. A fonte de dados armazena o resultado no contexto, que é transmitido para a resposta. A resposta retorna as `Posts` que foram recuperadas e, em seguida, define `nextToken` como a entrada `Post` logo após o limite. A próxima solicitação é enviada para fazer exatamente a mesma coisa, mas começando pelo deslocamento logo após a primeira consulta. Lembre-se de que esses tipos de solicitações são feitos sequencialmente e não de maneira simultânea.

# Testando e depurando resolvedores em () AWS AppSync JavaScript
<a name="test-debug-resolvers-js"></a>

AWS AppSync executa resolvedores em um campo GraphQL em relação a uma fonte de dados. Ao trabalhar com resolvedores de pipeline, as funções interagem com suas fontes de dados. Conforme descrito na [visão geral dos JavaScript resolvedores](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html), as funções se comunicam com as fontes de dados usando manipuladores de solicitação e resposta gravados JavaScript e executados no `APPSYNC_JS` tempo de execução. Isso permite fornecer lógica e condições personalizadas antes e depois da comunicação com a fonte de dados.

Para ajudar os desenvolvedores a escrever, testar e depurar esses resolvedores, o AWS AppSync console também fornece ferramentas para criar uma solicitação e uma resposta do GraphQL com dados simulados até o resolvedor de campo individual. Além disso, você pode realizar consultas, mutações e assinaturas no AWS AppSync console e ver um fluxo de log detalhado de toda a solicitação da Amazon. CloudWatch Isso inclui resultados da fonte de dados.

## Testes com dados simulados
<a name="testing-with-mock-data-js"></a>

Quando um resolvedor do GraphQL é invocado, ele contém um objeto `context` que contém informações relevantes sobre a solicitação. Isso inclui argumentos de um cliente, informações de identidade e dados do campo pai do GraphQL. Ele também armazena os resultados da fonte de dados, que podem ser usados no manipulador de respostas. Para obter mais informações sobre essa estrutura e os utilitários auxiliares disponíveis para usar durante a programação, consulte a [Referência do objeto de contexto do resolvedor](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html).

Ao escrever ou editar uma função de resolução, você pode passar um objeto de *contexto simulado* ou de *teste* para o editor do console. Isso permite que você veja como os manipuladores de solicitação e de resposta são avaliados sem realmente serem executados em uma fonte de dados. Por exemplo, você pode enviar um argumento `firstname: Shaggy` de teste e ver como ele avalia ao usar `ctx.args.firstname` no código do modelo. Você também pode testar a avaliação de qualquer utilitário auxiliar, como `util.autoId()` ou `util.time.nowISO8601()`.

### Teste de resolvedores
<a name="test-a-resolver-js"></a>

Este exemplo usará o AWS AppSync console para testar os resolvedores.

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

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

   1. Na **Barra lateral**, escolha **Funções**.

1. Escolha uma função existente.

1. Na parte superior da página **Atualizar função**, escolha **Selecionar contexto de teste** e, em seguida, escolha **Criar novo contexto**.

1. Selecione um objeto de contexto de amostra ou preencha o JSON manualmente na janela **Configurar contexto de teste**.

1. Insira um **nome de contexto de texto**.

1. Clique no botão **Salvar**.

1. Para avaliar o resolvedor usando esse objeto de contexto simulado, escolha **Executar teste**.

Como exemplo mais prático, digamos que você tenha um aplicativo que armazena um tipo do GraphQL `Dog` que usa a geração automática de ID para objetos e os armazena no Amazon DynamoDB. Você também deseja gravar alguns valores dos argumentos de uma mutação do GraphQL e permitir que apenas usuários específicos vejam uma resposta. O trecho a seguir mostra a aparência do esquema:

```
type Dog {
  breed: String
  color: String
}

type Mutation {
  addDog(firstname: String, age: Int): Dog
}
```

Você pode escrever uma AWS AppSync função e adicioná-la ao seu `addDog` resolvedor para lidar com a mutação. Para testar sua AWS AppSync função, você pode preencher um objeto de contexto, como no exemplo a seguir. Ele tem argumentos do cliente de `name` e `age`, e um `username` preenchido no objeto `identity`:

```
{
    "arguments" : {
        "firstname": "Shaggy",
        "age": 4
    },
    "source" : {},
    "result" : {
        "breed" : "Miniature Schnauzer",
        "color" : "black_grey"
    },
    "identity": {
        "sub" : "uuid",
        "issuer" : " https://cognito-idp.{region}.amazonaws.com/{userPoolId}",
        "username" : "Nadia",
        "claims" : { },
        "sourceIp" :[  "x.x.x.x" ],
        "defaultAuthStrategy" : "ALLOW"
    }
}
```

Você pode testar sua AWS AppSync função usando o seguinte código:

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  return {
    operation: 'PutItem',
    key: util.dynamodb.toMapValues({ id: util.autoId() }),
    attributeValues: util.dynamodb.toMapValues(ctx.args),
  };
}

export function response(ctx) {
  if (ctx.identity.username === 'Nadia') {
    console.log("This request is allowed")
    return ctx.result;
  }
  util.unauthorized();
}
```

O manipulador de solicitação e resposta avaliado possui os dados do objeto de contexto de teste e o valor gerado de `util.autoId()`. Além disso, se você alterasse o `username` para um valor diferente de `Nadia`, os resultados não seriam retornados pois a verificação de autorização falharia. Para obter mais informações sobre o controle de acesso refinado, consulte [Casos de uso de autorização](security-authorization-use-cases.md#aws-appsync-security-authorization-use-cases).

### Testando manipuladores de solicitações e respostas com's AWS AppSync APIs
<a name="testing-with-appsync-api-js"></a>

Você pode usar o comando API do `EvaluateCode` para testar remotamente seu código com dados simulados. Para começar a usar o comando, certifique-se de ter adicionado a permissão `appsync:evaluateMappingCode` à sua política. Por exemplo:

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

****  

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

------

Você pode aproveitar o comando usando o [AWS CLI](https://aws.amazon.com/cli/)ou [AWS SDKs](https://aws.amazon.com/tools/). Por exemplo, veja o `Dog` esquema e seus manipuladores de solicitação e resposta de AWS AppSync função da seção anterior. Usando a CLI em sua estação local, salve o código em um arquivo chamado `code.js` e salve o objeto `context` em um arquivo chamado `context.json`. No seu shell, execute o seguinte comando:

```
$ aws appsync evaluate-code \
  --code file://code.js \
  --function response \
  --context file://context.json \
  --runtime name=APPSYNC_JS,runtimeVersion=1.0.0
```

A resposta tem um `evaluationResult` contendo a carga retornada pelo seu manipulador. Também contém um objeto `logs` que contém a lista de logs que foram gerados pelo seu manipulador durante a avaliação. Isso facilita a depuração da execução do código e a visualização de informações sobre sua avaliação para ajudar na solução de problemas. Por exemplo:

```
{
    "evaluationResult": "{\"breed\":\"Miniature Schnauzer\",\"color\":\"black_grey\"}",
    "logs": [
        "INFO - code.js:13:5: \"This request is allowed\""
    ]
}
```

O `evaluationResult` pode ser analisado como JSON, que fornece: 

```
{
  "breed": "Miniature Schnauzer",
  "color": "black_grey"
}
```

Usando o SDK, você pode incorporar facilmente testes do seu conjunto de testes favorito para validar o comportamento dos seus manipuladores. Recomendamos a criação de testes usando o [Estrutura de trabalho de teste Jest](https://jestjs.io/), mas qualquer conjunto de testes funciona. O trecho a seguir mostra uma execução de validação hipotética. Esperamos que a resposta de avaliação seja um JSON válido, por isso, usamos `JSON.parse` para recuperar o JSON da resposta da string:

```
const AWS = require('aws-sdk')
const fs = require('fs')
const client = new AWS.AppSync({ region: 'us-east-2' })
const runtime = {name:'APPSYNC_JS',runtimeVersion:'1.0.0')

test('request correctly calls DynamoDB', async () => {
  const code = fs.readFileSync('./code.js', 'utf8')
  const context = fs.readFileSync('./context.json', 'utf8')
  const contextJSON = JSON.parse(context)
  
  const response = await client.evaluateCode({ code, context, runtime, function: 'request' }).promise()
  const result = JSON.parse(response.evaluationResult)
  
  expect(result.key.id.S).toBeDefined()
  expect(result.attributeValues.firstname.S).toEqual(contextJSON.arguments.firstname)
})
```

 Isso produz o seguinte resultado:

```
Ran all test suites.
> jest

PASS ./index.test.js
✓ request correctly calls DynamoDB (543 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 totalTime: 1.511 s, estimated 2 s
```

## Depuração de uma consulta atual
<a name="debugging-a-live-query-js"></a>

Não há substituto para um end-to-end teste e um registro para depurar um aplicativo de produção. AWS AppSync permite que você registre erros e detalhes completos da solicitação usando a Amazon CloudWatch. Além disso, você pode usar o AWS AppSync console para testar consultas, mutações e assinaturas do GraphQL e transmitir ao vivo os dados de log de cada solicitação de volta ao editor de consultas para depuração em tempo real. Para assinaturas, os logs exibem as informações do tempo de conexão.

Para fazer isso, você precisa ter CloudWatch os registros da Amazon habilitados com antecedência, conforme descrito em [Monitoramento e registro](monitoring.md#aws-appsync-monitoring). Em seguida, no AWS AppSync console, escolha a guia **Consultas** e insira uma consulta GraphQL válida. Na seção inferior direita, clique e arraste a janela **Registros em log** para abrir a visualização de registros. No topo da página, escolha o ícone de seta de reprodução para executar a consulta do GraphQL. Em alguns instantes, os logs completos da solicitação e da resposta para a operação serão transmitidos para essa seção e você poderá visualizá-los no console.

# Configurando e usando resolvedores de pipeline em AWS AppSync () JavaScript
<a name="pipeline-resolvers-js"></a>

AWS AppSync executa resolvedores em um campo GraphQL. Em alguns casos, os aplicativos requerem a execução de várias operações para resolver um único campo do GraphQL. Com os resolvedores de pipeline, os desenvolvedores agora podem elaborar operações chamadas Funções e executá-las em sequência. Os resolvedores de pipeline são úteis para aplicativos que, por exemplo, exigem a execução de uma verificação de autorização antes de obter dados para um campo.

Para obter mais informações sobre a arquitetura de um resolvedor de JavaScript pipeline, consulte a [visão geral dos JavaScript resolvedores](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html#anatomy-of-a-pipeline-resolver-js).

## Etapa 1: criar um resolvedor de pipeline
<a name="create-a-pipeline-resolver-js"></a>

No AWS AppSync console, acesse a página **Esquema**.

Salve o seguinte esquema:

```
schema {
    query: Query
    mutation: Mutation
}

type Mutation {
    signUp(input: Signup): User
}

type Query {
    getUser(id: ID!): User
}

input Signup {
    username: String!
    email: String!
}

type User {
    id: ID!
    username: String
    email: AWSEmail
}
```

Vamos conectar um resolvedor de pipeline ao campo **signUp** no tipo **Mutação**. No tipo **Mutação** no lado direito, escolha **Anexar** ao lado do campo de mutação `signUp`. Defina o resolvedor como `pipeline resolver` e o runtime `APPSYNC_JS` e, em seguida, crie o resolvedor.

Nosso resolvedor de pipeline cadastra um usuário validando primeiro a entrada do endereço de e-mail e salvando o usuário no sistema. Vamos encapsular a validação de e-mail dentro de uma função **validateEmail** e salvar o usuário dentro de uma função **saveUser**. A função **validateEmail** é executada primeiro e, se o e-mail for válido, a função **saveUser** será executada.

O fluxo de execução será da seguinte forma:

1. Manipulador de solicitações do resolvedor Mutation.signUp

1. Função validateEmail

1. Função saveUser

1. Manipulador de respostas do resolvedor Mutation.signUp

Provavelmente reutilizaremos a função **validateEmail** em outros resolvedores em nossa API. Sendo assim, queremos evitar o acesso a `ctx.args`, já que eles mudarão de um campo do GraphQL para outro. Em vez disso, podemos usar o `ctx.stash` para armazenar o atributo de e-mail a partir do argumento de campo de entrada `signUp(input: Signup)`.

Atualize seu código de resolvedor substituindo as funções de solicitação e resposta:

```
export function request(ctx) {
    ctx.stash.email = ctx.args.input.email
    return {};
}

export function response(ctx) {
    return ctx.prev.result;
}
```

Escolha **Criar** ou **Salvar** para atualizar o resolvedor.

## Etapa 2: criar uma função
<a name="create-a-function-js"></a>

Na página do resolvedor de pipeline, na seção **Funções**, clique em **Adicionar função** e em **Criar função**. Também é possível criar funções sem passar pela página do resolvedor; para fazer isso, no AWS AppSync console, acesse a página **Funções**. Selecione o botão **Criar função**. Vamos criar uma função que verifique se um e-mail é válido e proveniente de um domínio específico. Se o e-mail não for válido, a função gerará um erro. Caso contrário, ele encaminha qualquer entrada fornecida.

Crie uma fonte de dados do tipo **NONE**. Escolha a fonte de dados na lista **Nome da fonte de dados**. Em **nome da função**, insira `validateEmail`. Na área **código da função**, substitua tudo por este trecho:

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  const { email } = ctx.stash;
  const valid = util.matches(
    '^[a-zA-Z0-9_.+-]+@(?:(?:[a-zA-Z0-9-]+\.)?[a-zA-Z]+\.)?(myvaliddomain)\.com',
    email
  );
  if (!valid) {
    util.error(`"${email}" is not a valid email.`);
  }

  return { payload: { email } };
}

export function response(ctx) {
  return ctx.result;
}
```

Revise suas entradas e selecione **Criar**. Acabamos de criar nossa função **validateEmail**. Repita essas etapas para criar a função **saveUser** com o código a seguir (para simplificar, usamos a fonte de dados **NONE** e fingimos que o usuário foi salvo no sistema após a execução da função.):

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
  return ctx.prev.result;
}

export function response(ctx) {
  ctx.result.id = util.autoId();
  return ctx.result;
}
```

Acabamos de criar nossa função **saveUser**.

## Etapa 3: adicionar uma função a um resolvedor de pipeline
<a name="adding-a-function-to-a-pipeline-resolver-js"></a>

Nossas funções devem ter sido adicionadas automaticamente ao resolvedor de pipeline que acabamos de criar. Se não foi esse o caso ou se você criou as funções por meio da página **Funções**, é possível clicar em **Adicionar função** na página do `signUp` resolvedor para anexá-las. Adicione as funções **validateEmail** e **saveUser** ao resolvedor. A função **validateEmail** deve ser colocada antes da função **saveUser**. À medida que você adiciona mais funções, pode usar as setas **para cima** e **para baixo** para reorganizar a ordem de execução das funções. Revise suas alterações e escolha **Salvar**.

## Etapa 4: executar uma consulta
<a name="running-a-query-js"></a>

No AWS AppSync console, acesse a página **Consultas.** No explorador, verifique se você está usando a mutação. Se não estiver, escolha `Mutation` na lista suspensa e escolha `+`. Digite a consulta a seguir:

```
mutation {
  signUp(input: {email: "nadia@myvaliddomain.com", username: "nadia"}) {
    id
    username
  }
}
```

Ela deve retornar algo semelhante a:

```
{
  "data": {
    "signUp": {
      "id": "256b6cc2-4694-46f4-a55e-8cb14cc5d7fc",
      "username": "nadia"
    }
  }
}
```

Cadastramos com sucesso nosso usuário e validamos o e-mail de entrada usando um resolvedor de pipeline.

# Criação de consultas básicas (VTL)
<a name="configuring-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/configuring-resolvers-js.html).

Os resolvedores do GraphQL conectam os campos em um esquema de tipo a uma fonte de dados. Os resolvedores são o mecanismo pelo qual as solicitações são atendidas. AWS AppSync pode criar e conectar automaticamente resolvedores a partir de um esquema ou criar um esquema e conectar resolvedores de uma tabela existente sem precisar escrever nenhum código.

Resolvedores em AWS AppSync uso JavaScript para converter uma expressão GraphQL em um formato que a fonte de dados possa usar. Como alternativa, os modelos de mapeamento podem ser escritos em [Apache VTL (Velocity Template Language)](https://velocity.apache.org/engine/2.0/vtl-reference.html) para converter uma expressão de GraphQL em um formato que a fonte de dados possa usar.

Esta seção mostrará como configurar resolvedores de VTL. [Um guia introdutório de programação em estilo tutorial para escrever resolvedores pode ser encontrado no guia de programação do [modelo de mapeamento do Resolver e os utilitários auxiliares disponíveis para uso durante a programação](resolver-mapping-template-reference-programming-guide.md#aws-appsync-resolver-mapping-template-reference-programming-guide) podem ser encontrados na referência de contexto do modelo de mapeamento do Resolver.](resolver-context-reference.md#aws-appsync-resolver-mapping-template-context-reference) AWS AppSync também tem fluxos de teste e depuração integrados que você pode usar ao editar ou criar do zero. Para obter mais informações, consulte [Resolvedores de teste e depuração](test-debug-resolvers.md#aws-appsync-test-debug-resolvers).

Recomendamos seguir este guia antes de tentar usar qualquer um dos tutoriais mencionados acima.

Nesta seção, vamos criar um resolvedor, adicionar um resolvedor para mutações e usar as configurações avançadas.

## Criar seu primeiro resolvedor
<a name="create-your-first-resolver"></a>

Seguindo os exemplos das seções anteriores, a primeira etapa é criar um resolvedor para seu tipo de `Query`.

------
#### [ Console ]

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 **Esquema**.

1. No lado direito da página, há uma janela chamada **Resolvedores**. Essa caixa contém uma lista dos tipos e campos conforme definido na janela **Esquema** no lado esquerdo da página. Você pode anexar resolvedores aos campos. Por exemplo, no tipo de **consulta**, escolha **Anexar** ao lado do campo `getTodos`.

1. Na página **Criar resolvedor**, escolha a fonte de dados que você criou no guia [Anexar uma fonte de dados](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html). Na janela **Configurar modelos de mapeamento**, você pode escolher os modelos genéricos de mapeamento de solicitação e resposta na lista suspensa à direita ou escrever suas próprias opções.
**nota**  
A combinação de um modelo de mapeamento de solicitação com um modelo de mapeamento de resposta é chamado de resolvedor de unidades. Os resolvedores de unidades normalmente são destinados a realizar operações rotineiras, e recomendamos usá-los somente para operações individuais com um pequeno número de fontes de dados. Para operações mais complexas, recomendamos o uso de resolvedores de pipeline, que podem executar diversas operações com várias fontes de dados sequencialmente.  
Para obter mais informações sobre a diferença entre os modelos de mapeamento de solicitação e resposta, consulte [Resolvedores de unidades](https://docs.aws.amazon.com//appsync/latest/devguide/resolver-mapping-template-reference-overview.html#unit-resolvers).  
Para obter mais informações sobre o uso de resolvedores de pipeline, consulte [Resolvedores de pipeline](pipeline-resolvers.md#aws-appsync-pipeline-resolvers).

1. Para casos de uso comuns, o AWS AppSync console tem modelos integrados que você pode usar para obter itens de fontes de dados (por exemplo, todas as consultas de itens, pesquisas individuais etc.). Por exemplo, na versão simples do esquema de [Projetar seu esquema](designing-your-schema.md#aws-appsync-designing-your-schema), onde `getTodos` não tinha paginação, o modelo de mapeamento para listar os itens é o seguinte:

   ```
   {
       "version" : "2017-02-28",
       "operation" : "Scan"
   }
   ```

1. Sempre é necessário ter um modelo de mapeamento da resposta para acompanhar a solicitação. O console fornece um padrão com o seguinte valor de passagem para listas:

   ```
   $util.toJson($ctx.result.items)
   ```

   Neste exemplo, o objeto `context` (com o alias de `$ctx`) para listas de itens tem o formato `$context.result.items`. Se a operação do GraphQL retorna um único item, ele seria `$context.result`. O AWS AppSync oferece funções auxiliares para operações comuns, como a função `$util.toJson` listada anteriormente, para formatar respostas corretamente. Para obter uma lista completa das funções, consulte [Referência do utilitário do modelo de mapeamento do resolvedor](resolver-util-reference.md#aws-appsync-resolver-mapping-template-util-reference).

1. Escolha **Salvar resolvedor**.

------
#### [ API ]

1. Crie um objeto resolvedor chamando a API [https://docs.aws.amazon.com/appsync/latest/APIReference/API_CreateResolver.html](https://docs.aws.amazon.com/appsync/latest/APIReference/API_CreateResolver.html).

1. Você pode modificar os campos do seu resolvedor chamando a API [https://docs.aws.amazon.com/appsync/latest/APIReference/API_UpdateResolver.html](https://docs.aws.amazon.com/appsync/latest/APIReference/API_UpdateResolver.html).

------
#### [ CLI ]

1. Crie um resolvedor executando o comando [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html).

   Você precisará digitar 6 parâmetros para este comando específico:

   1. O `api-id` da sua API.

   1. O `type-name` do tipo que você deseja modificar em seu esquema. No exemplo do console, tínhamos `Query`.

   1. O `field-name` do tipo que você deseja modificar em seu tipo. No exemplo do console, tínhamos `getTodos`.

   1. A fonte de dados `data-source-name` que você criou no guia [Anexar uma fonte de dados](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html).

   1. O `request-mapping-template`, que é o corpo da solicitação. No exemplo do console, tínhamos:

      ```
      {
          "version" : "2017-02-28",
          "operation" : "Scan"
      }
      ```

   1. O `response-mapping-template`, que é o corpo da resposta. No exemplo do console, tínhamos:

      ```
      $util.toJson($ctx.result.items)
      ```

   Veja um exemplo de comando:

   ```
   aws appsync create-resolver --api-id abcdefghijklmnopqrstuvwxyz --type-name Query --field-name getTodos --data-source-name TodoTable --request-mapping-template "{ "version" : "2017-02-28", "operation" : "Scan", }" --response-mapping-template ""$"util.toJson("$"ctx.result.items)"
   ```

   Uma saída será retornada na CLI. Veja um exemplo abaixo:

   ```
   {
       "resolver": {
           "kind": "UNIT",
           "dataSourceName": "TodoTable",
           "requestMappingTemplate": "{ version : 2017-02-28, operation : Scan, }",
           "resolverArn": "arn:aws:appsync:us-west-2:107289374856:apis/abcdefghijklmnopqrstuvwxyz/types/Query/resolvers/getTodos",
           "typeName": "Query",
           "fieldName": "getTodos",
           "responseMappingTemplate": "$util.toJson($ctx.result.items)"
       }
   }
   ```

1. Para modificar os modelos de and/or mapeamento de campos de um resolvedor, execute o [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-resolver.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-resolver.html)comando.

   Com exceção do parâmetro de `api-id`, os parâmetros usados no comando `create-resolver` serão substituídos pelos novos valores do comando `update-resolver`.

------

## Adicionar um resolvedor para mutações
<a name="adding-a-resolver-for-mutations"></a>

A próxima etapa é criar um resolvedor para seu tipo de `Mutation`.

------
#### [ Console ]

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 **Esquema**.

1. No tipo **Mutação**, escolha **Anexar** ao lado do seu campo `addTodo`.

1. Na página **Criar resolvedor**, escolha a fonte de dados que você criou no guia [Anexar uma fonte de dados](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html).

1. Na janela **Configurar modelos de mapeamento**, você precisará modificar o modelo de solicitação porque essa é uma mutação em que você está adicionando um novo item ao DynamoDB. Use o seguinte modelo de mapeamento da solicitação:

   ```
   {
       "version" : "2017-02-28",
       "operation" : "PutItem",
       "key" : {
           "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
       },
       "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args)
   }
   ```

1. AWS AppSync converte automaticamente os argumentos definidos no `addTodo` campo do seu esquema do GraphQL em operações do DynamoDB. O exemplo anterior armazena registros no DynamoDB usando uma chave do `id` que é transmitida a partir do argumento da mutação como `$ctx.args.id`. Todos os outros campos transmitidos são mapeados automaticamente para atributos do DynamoDB com `$util.dynamodb.toMapValuesJson($ctx.args)`.

   Para esse resolvedor, use o seguinte modelo de mapeamento da resposta:

   ```
   $util.toJson($ctx.result)
   ```

   AWS AppSync também suporta fluxos de trabalho de teste e depuração para edição de resolvedores. Use um objeto `context` de simulação para ver o valor transformado do modelo antes de invocar. Opcionalmente, você pode visualizar a execução de solicitação completa para uma fonte de dados de forma interativa ao executar uma consulta. Para obter mais informações, consulte [Resolvedores de teste e depuração](test-debug-resolvers.md#aws-appsync-test-debug-resolvers) e o [Monitoramento e registro em log](monitoring.md#aws-appsync-monitoring).

1. Escolha **Salvar resolvedor**.

------
#### [ API ]

Você também pode fazer isso APIs utilizando os comandos na seção [Criar seu primeiro resolvedor](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html#create-your-first-resolver) e os detalhes dos parâmetros desta seção.

------
#### [ CLI ]

Além disso, é possível fazer isso no CLI utilizando os comandos na seção [Criar seu primeiro resolvedor](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html#create-your-first-resolver) e os detalhes dos parâmetros desta seção.

------

Neste momento, se não estiver usando os resolvedores avançados você pode começar a usar a API GraphQL conforme descrito em [Uso da API](using-your-api.md#aws-appsync-using-your-api).

## Resolvedores avançados
<a name="advanced-resolvers"></a>

Se estiver seguindo a seção Avançado e estiver criando um esquema de exemplo em [Projetar seu esquema](designing-your-schema.md#aws-appsync-designing-your-schema) para fazer uma verificação paginada, use o seguinte modelo de solicitação para o campo `getTodos`:

```
{
    "version" : "2017-02-28",
    "operation" : "Scan",
    "limit": $util.defaultIfNull(${ctx.args.limit}, 20),
    "nextToken": $util.toJson($util.defaultIfNullOrBlank($ctx.args.nextToken, null))
}
```

Para esse caso de uso de paginação, o mapeamento da resposta é mais do que apenas uma passagem porque ele deve conter o *cursor* (para que o cliente saiba em qual página começar) e o conjunto de resultados. O modelo de mapeamento é conforme mostrado a seguir:

```
{
    "todos": $util.toJson($context.result.items),
    "nextToken": $util.toJson($context.result.nextToken)
}
```

Os campos no modelo de mapeamento da resposta anterior devem corresponder aos campos definidos no tipo `TodoConnection`.

Se houver relações em que há uma tabela de `Comments`, e você estiver resolvendo o campo dos comentários no tipo `Todo` (que retorna um tipo de `[Comment]`), use um modelo de mapeamento que executa uma consulta mediante a segunda tabela. Para fazer isso, é necessário já ter criado uma fonte de dados para a tabela `Comments`, conforme descrito em Associar uma fonte de dados.

**nota**  
Estamos usando uma operação de consulta mediante uma segunda tabela somente para fins ilustrativos. Você pode usar outra operação mediante o DynamoDB no lugar. Além disso, você pode extrair os dados de outra fonte de dados, como AWS Lambda o Amazon OpenSearch Service, porque a relação é controlada pelo esquema do GraphQL.

------
#### [ Console ]

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 **Esquema**.

1. No tipo **Tarefas**, escolha **Anexar** ao lado do seu campo `comments`.

1. Na página **Criar resolvedor**, escolha sua fonte de dados da tabela de **comentários**. O nome padrão da tabela **Comentários** nos guias de início rápido é `AppSyncCommentTable`, mas pode variar dependendo do nome que você atribuiu a ela.

1. Adicione o seguinte trecho ao seu modelo de mapeamento da solicitação:

   ```
   {
       "version": "2017-02-28",
       "operation": "Query",
       "index": "todoid-index",
       "query": {
           "expression": "todoid = :todoid",
           "expressionValues": {
               ":todoid": {
                   "S": $util.toJson($context.source.id)
               }
           }
       }
   }
   ```

1. O `context.source` faz referência ao objeto pai do campo atual que está sendo resolvido. Neste exemplo, `source.id` se refere ao objeto `Todo` individual que é, então, usado para a expressão de consulta.

   Você pode usar o modelo de mapeamento da resposta de passagem da seguinte forma:

   ```
   $util.toJson($ctx.result.items)
   ```

1. Escolha **Salvar resolvedor**.

1. Por fim, de volta à página **Esquema** no console, anexe um resolvedor ao campo `addComment` e especifique a fonte de dados da tabela `Comments`. Neste caso, o modelo de mapeamento da solicitação é um simples `PutItem` com o `todoid` específico que está comentado como um argumento, mas use o utilitário `$utils.autoId()` para criar uma chave de classificação única para o comentário da seguinte forma:

   ```
   {
       "version": "2017-02-28",
       "operation": "PutItem",
       "key": {
           "todoid": { "S": $util.toJson($context.arguments.todoid) },
           "commentid": { "S": "$util.autoId()" }
       },
       "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args)
   }
   ```

   Use um modelo da resposta de passagem da seguinte forma:

   ```
   $util.toJson($ctx.result)
   ```

------
#### [ API ]

Você também pode fazer isso APIs utilizando os comandos na seção [Criar seu primeiro resolvedor](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html#create-your-first-resolver) e os detalhes dos parâmetros desta seção.

------
#### [ CLI ]

Além disso, é possível fazer isso no CLI utilizando os comandos na seção [Criar seu primeiro resolvedor](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html#create-your-first-resolver) e os detalhes dos parâmetros desta seção.

------

# Como desabilitar modelos de mapeamento VTL com resolvedores diretos do Lambda (VTL)
<a name="direct-lambda-reference"></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/configuring-resolvers-js.html).

Com resolvedores Lambda diretos, você pode contornar o uso de modelos de mapeamento VTL ao usar fontes de dados. AWS Lambda AWS AppSync pode fornecer uma carga padrão para sua função Lambda, bem como uma tradução padrão da resposta de uma função Lambda para um tipo GraphQL. Você pode optar por fornecer um modelo de solicitação, um modelo de resposta ou nenhum dos dois e AWS AppSync tratará isso adequadamente. 

Para saber mais sobre a carga útil padrão da solicitação e a tradução de respostas que AWS AppSync fornece, consulte a referência do resolvedor do [Direct Lambda](resolver-mapping-template-reference-lambda.md#direct-lambda-resolvers). Para obter mais informações sobre como configurar uma fonte de AWS Lambda dados e configurar uma política de confiança do IAM, consulte [Anexar uma fonte de dados](attaching-a-data-source.md). 

## Configurar resolvedores diretos do Lambda
<a name="direct-lambda-reference-resolvers"></a>

As seções a seguir mostrarão como anexar fontes de dados do Lambda e adicionar resolvedores do Lambda aos seus campos.

### Adicionar uma fonte de dados do Lambda
<a name="direct-lambda-datasource"></a>

Antes de ativar os resolvedores diretos do Lambda, você deve adicionar uma fonte de dados do Lambda.

------
#### [ Console ]

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

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

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

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

   1. Para **Nome da fonte de dados**, digite um nome para sua fonte de dados, como **myFunction**. 

   1. Para **Tipo de fonte de dados**, escolha a opção **Função AWS Lambda **.

   1. Para **Região**, escolha a região apropriada.

   1. Para **Função ARN**, escolha a função do Lambda na lista suspensa. Você pode pesquisar o nome da função ou inserir manualmente o ARN da função que deseja usar. 

   1. Crie um perfil do IAM (recomendado) ou escolha uma função existente que tenha permissão `lambda:invokeFunction` do IAM. 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. Selecione o botão **Criar**.

------
#### [ CLI ]

1. Crie um objeto da fonte de dados executando o comando [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-data-source.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-data-source.html).

   Você precisará digitar 4 parâmetros para esse comando específico:

   1. O `api-id` da sua API.

   1. O `name` da sua fonte de dados. No exemplo do console, esse é o **Nome da fonte de dados**.

   1. O `type` da fonte de dados. No exemplo do console, isso é **função AWS Lambda **.

   1. O `lambda-config`, que é o **ARN da função** no exemplo do console.
**nota**  
Existem outros parâmetros, como `Region`, que devem ser configurados, mas geralmente usam como padrão os valores de configuração da CLI.

   Veja um exemplo de comando:

   ```
   aws appsync create-data-source --api-id abcdefghijklmnopqrstuvwxyz --name myFunction --type AWS_LAMBDA --lambda-config lambdaFunctionArn=arn:aws:lambda:us-west-2:102847592837:function:appsync-lambda-example
   ```

   Uma saída será retornada na CLI. Veja um exemplo abaixo:

   ```
   {
       "dataSource": {
           "dataSourceArn": "arn:aws:appsync:us-west-2:102847592837:apis/abcdefghijklmnopqrstuvwxyz/datasources/myFunction",
           "type": "AWS_LAMBDA",
           "name": "myFunction",
           "lambdaConfig": {
               "lambdaFunctionArn": "arn:aws:lambda:us-west-2:102847592837:function:appsync-lambda-example"
           }
       }
   }
   ```

1. Para modificar os atributos de uma fonte de dados, execute o comando [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-data-source.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/update-data-source.html).

   Com exceção do `api-id` parâmetro, os parâmetros usados no comando `create-data-source` serão substituídos pelos novos valores do comando `update-data-source`.

------

### Ativar resolvedores diretos do Lambda
<a name="direct-lambda-enable-templates"></a>

Depois de criar uma fonte de dados Lambda e configurar a função apropriada do IAM AWS AppSync para permitir a invocação da função, você pode vinculá-la a uma função de resolução ou pipeline. 

------
#### [ Console ]

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

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

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

1. Na janela **Resolvedores**, selecione um campo ou operação e selecione o botão **Anexar**.

1. Na página **Criar novo resolvedor**, escolha a função do Lambda na lista suspensa.

1. Para aproveitar os resolvedores diretos do Lambda, confirme se os modelos de mapeamento de solicitação e resposta estão desativados na seção **Configurar modelos de mapeamento**.

1. Selecione o botão **Salvar resolvedor**.

------
#### [ CLI ]
+ Crie um resolvedor executando o comando [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/appsync/create-resolver.html).

  Você precisará digitar 6 parâmetros para este comando específico:

  1. O `api-id` da sua API.

  1. O `type-name` do tipo no seu esquema.

  1. O `field-name` do campo no seu esquema.

  1. O `data-source-name`, ou o nome da sua função do Lambda.

  1. O `request-mapping-template`, que é o corpo da solicitação. No exemplo do console, desabilitamos o seguinte:

     ```
     " "
     ```

  1. O `response-mapping-template`, que é o corpo da resposta. No exemplo do console, o seguinte também foi desabilitado:

     ```
     " "
     ```

  Veja um exemplo de comando:

  ```
  aws appsync create-resolver --api-id abcdefghijklmnopqrstuvwxyz --type-name Subscription --field-name onCreateTodo --data-source-name LambdaTest --request-mapping-template " " --response-mapping-template " "
  ```

  Uma saída será retornada na CLI. Veja um exemplo abaixo:

  ```
  {
      "resolver": {
          "resolverArn": "arn:aws:appsync:us-west-2:102847592837:apis/abcdefghijklmnopqrstuvwxyz/types/Subscription/resolvers/onCreateTodo",
          "typeName": "Subscription",
          "kind": "UNIT",
          "fieldName": "onCreateTodo",
          "dataSourceName": "LambdaTest"
      }
  }
  ```

------

Quando você desativa seus modelos de mapeamento, há vários comportamentos adicionais que ocorrerão no AWS AppSync:
+ Ao desativar um modelo de mapeamento, você está sinalizando AWS AppSync que aceita as traduções de dados padrão especificadas na referência do resolvedor do Direct [Lambda](resolver-mapping-template-reference-lambda.md#direct-lambda-resolvers).
+ Ao desativar o modelo de mapeamento de solicitações, sua fonte de dados do Lambda receberá uma payload que consiste em todo o objeto [Contexto](resolver-context-reference.md).
+ Ao desativar o modelo de mapeamento de resposta, o resultado da sua invocação do Lambda será traduzido de acordo com a versão do modelo de mapeamento da solicitação ou se o modelo de mapeamento da solicitação também estiver desativado. 

# Testando e depurando resolvedores em (VTL) AWS AppSync
<a name="test-debug-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/configuring-resolvers-js.html).

AWS AppSync executa resolvedores em um campo GraphQL em relação a uma fonte de dados. Conforme descrito na [Visão geral do modelo de mapeamento do resolvedor](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview), os resolvedores se comunicam com as fontes de dados usando uma linguagem de modelos. Isso permite personalizar o comportamento e aplicar lógica e condições antes e depois de se comunicar com a fonte de dados. Para obter um guia de programação introdutório no estilo tutorial para programar resolvedores, consulte o [Guia de programação do modelo de mapeamento do resolvedor](resolver-mapping-template-reference-programming-guide.md#aws-appsync-resolver-mapping-template-reference-programming-guide).

Para ajudar os desenvolvedores a escrever, testar e depurar esses resolvedores, o AWS AppSync console também fornece ferramentas para criar uma solicitação e uma resposta do GraphQL com dados simulados até o resolvedor de campo individual. Além disso, você pode realizar consultas, mutações e assinaturas no AWS AppSync console e ver um stream de log detalhado da Amazon CloudWatch de toda a solicitação. Isso inclui os resultados de uma fonte de dados.

## Testes com dados simulados
<a name="testing-with-mock-data"></a>

Quando um resolvedor do GraphQL é invocado, ele contém um objeto `context` que contém informações sobre a solicitação. Isso inclui argumentos de um cliente, informações de identidade e dados do campo pai do GraphQL. Ele também contém os resultados da fonte de dados, que podem ser usados no modelo da resposta. Para obter mais informações sobre essa estrutura e os utilitários auxiliares disponíveis para o uso ao programar, consulte a [Referência de contexto do modelo de mapeamento do resolvedor](resolver-context-reference.md#aws-appsync-resolver-mapping-template-context-reference).

Ao escrever ou editar um resolvedor, você pode passar um objeto de *contexto simulado* ou de *teste* para o editor do console. Isso permite ver como os modelos de solicitação e resposta avaliam, sem realmente executar segundo uma fonte de dados. Por exemplo, você pode enviar um argumento `firstname: Shaggy` de teste e ver como ele avalia ao usar `$ctx.args.firstname` no código do modelo. Você também pode testar a avaliação de qualquer utilitário auxiliar, como `$util.autoId()` ou `util.time.nowISO8601()`.

### Teste de resolvedores
<a name="test-a-resolver"></a>

Este exemplo usará o AWS AppSync console para testar os resolvedores.

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

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

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

1. Se ainda não tiver feito isso, no tipo e ao lado do campo, escolha **Anexar** para adicionar seu resolvedor.

   Para obter mais informações sobre como construir um resolvedor completo, consulte [Configuração de resolvedores](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers.html).

   Caso contrário, selecione o resolvedor que já está no campo.

1. Na parte superior da página **Editar resolvedor**, escolha **Selecionar contexto de teste** e escolha **Criar novo contexto**.

1. Selecione um objeto de contexto de amostra ou preencha o JSON manualmente na janela **Contexto de execução**.

1. Insira um **Nome de contexto de texto**.

1. Clique no botão **Salvar**.

1. Na parte superior da página **Editar resolvedor**, escolha **Executar teste**.

Como exemplo mais prático, digamos que você tenha um aplicativo que armazena um tipo do GraphQL `Dog` que usa a geração automática de ID para objetos e os armazena no Amazon DynamoDB. Você também deseja gravar alguns valores dos argumentos de uma mutação do GraphQL e permitir que apenas usuários específicos vejam uma resposta. Veja a seguir a possível aparência do esquema:

```
type Dog {
  breed: String
  color: String
}

type Mutation {
  addDog(firstname: String, age: Int): Dog
}
```

Ao adicionar um resolvedor para a mutação `addDog`, preencha um objeto de contexto como o exemplo a seguir. Ele tem argumentos do cliente de `name` e `age`, e um `username` preenchido no objeto `identity`:

```
{
    "arguments" : {
        "firstname": "Shaggy",
        "age": 4
    },
    "source" : {},
    "result" : {
        "breed" : "Miniature Schnauzer",
        "color" : "black_grey"
    },
    "identity": {
        "sub" : "uuid",
        "issuer" : " https://cognito-idp.{region}.amazonaws.com/{userPoolId}",
        "username" : "Nadia",
        "claims" : { },
        "sourceIp" :[  "x.x.x.x" ],
        "defaultAuthStrategy" : "ALLOW"
    }
}
```

Você pode testar isso usando os seguintes modelos de mapeamento da solicitação e da resposta:

 **Modelo de solicitação** 

```
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key" : {
        "id" : { "S" : "$util.autoId()" }
    },
    "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args)
}
```

 **Modelo da resposta** 

```
#if ($context.identity.username == "Nadia")
  $util.toJson($ctx.result)
#else
  $util.unauthorized()
#end
```

O modelo avaliado tem os dados do objeto de contexto de teste e o valor gerado de `$util.autoId()`. Além disso, se você alterasse o `username` para um valor diferente de `Nadia`, os resultados não seriam retornados pois a verificação de autorização falharia. Para obter mais informações sobre o controle de acesso refinado, consulte [Casos de uso de autorização](security-authorization-use-cases.md#aws-appsync-security-authorization-use-cases).

### Testando modelos de mapeamento com AWS AppSync APIs
<a name="testing-with-appsync-api"></a>

Você pode usar o comando da API `EvaluateMappingTemplate` para testar remotamente seus modelos de mapeamento com dados simulados. Para começar a usar o comando, certifique-se de ter adicionado a permissão `appsync:evaluateMappingTemplate` à sua política. Por exemplo:

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

****  

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

------

Você pode aproveitar o comando usando o [AWS CLI](https://aws.amazon.com/cli/)ou [AWS SDKs](https://aws.amazon.com/tools/). Por exemplo, veja o `Dog` esquema e seus modelos de request/response mapeamento da seção anterior. Usando a CLI em sua estação local, salve o modelo de solicitação em um arquivo chamado `request.vtl` e salve o objeto `context` em um arquivo chamado `context.json`. No seu shell, execute o seguinte comando:

```
aws appsync evaluate-mapping-template --template file://request.vtl --context file://context.json
```

O comando retorna a seguinte resposta:

```
{
  "evaluationResult": "{\n    \"version\" : \"2017-02-28\",\n    \"operation\" : \"PutItem\",\n    \"key\" : {\n        \"id\" : { \"S\" : \"afcb4c85-49f8-40de-8f2b-248949176456\" }\n    },\n    \"attributeValues\" : {\"firstname\":{\"S\":\"Shaggy\"},\"age\":{\"N\":4}}\n}\n"
}
```

O `evaluationResult` contém os resultados do teste do modelo fornecido com o `context` fornecido. Você também pode testar seus modelos usando AWS SDKs o. Aqui está um exemplo usando o AWS SDK para JavaScript V2: 

```
const AWS = require('aws-sdk')
const client = new AWS.AppSync({ region: 'us-east-2' })

const template = fs.readFileSync('./request.vtl', 'utf8')
const context = fs.readFileSync('./context.json', 'utf8')

client
  .evaluateMappingTemplate({ template, context })
  .promise()
  .then((data) => console.log(data))
```

Usando o SDK, você pode incorporar facilmente testes do seu conjunto de testes favorito para validar o comportamento do seu modelo. Recomendamos a criação de testes usando o [Estrutura de trabalho de teste Jest](https://jestjs.io/), mas qualquer conjunto de testes funciona. O trecho a seguir mostra uma execução de validação hipotética. Esperamos que a resposta de avaliação seja um JSON válido, por isso, usamos `JSON.parse` para recuperar o JSON da resposta da string:

```
const AWS = require('aws-sdk')
const fs = require('fs')
const client = new AWS.AppSync({ region: 'us-east-2' })

test('request correctly calls DynamoDB', async () => {
  const template = fs.readFileSync('./request.vtl', 'utf8')
  const context = fs.readFileSync('./context.json', 'utf8')
  const contextJSON = JSON.parse(context)
  
  const response = await client.evaluateMappingTemplate({ template, context }).promise()
  const result = JSON.parse(response.evaluationResult)
  
  expect(result.key.id.S).toBeDefined()
  expect(result.attributeValues.firstname.S).toEqual(contextJSON.arguments.firstname)
})
```

 Isso produz o seguinte resultado:

```
Ran all test suites.
> jest

PASS ./index.test.js
✓ request correctly calls DynamoDB (543 ms)

Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.511 s, estimated 2 s
```

## Depuração de uma consulta atual
<a name="debugging-a-live-query"></a>

Não há substituto para um end-to-end teste e um registro para depurar um aplicativo de produção. AWS AppSync permite que você registre erros e detalhes completos da solicitação usando a Amazon CloudWatch. Além disso, você pode usar o AWS AppSync console para testar consultas, mutações e assinaturas do GraphQL e transmitir ao vivo os dados de log de cada solicitação de volta ao editor de consultas para depuração em tempo real. Para assinaturas, os logs exibem as informações do tempo de conexão.

Para fazer isso, você precisa ter CloudWatch os registros da Amazon habilitados com antecedência, conforme descrito em [Monitoramento e registro](monitoring.md#aws-appsync-monitoring). Em seguida, no AWS AppSync console, escolha a guia **Consultas** e insira uma consulta GraphQL válida. Na seção inferior direita, clique e arraste a janela **Registros em log** para abrir a visualização de registros. No topo da página, escolha o ícone de seta de reprodução para executar a consulta do GraphQL. Em alguns instantes, os logs completos da solicitação e da resposta para a operação serão transmitidos para essa seção e você poderá visualizá-los no console.

# Configurando e usando resolvedores de pipeline em AWS AppSync (VTL)
<a name="pipeline-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/configuring-resolvers-js.html).

AWS AppSync executa resolvedores em um campo GraphQL. Em alguns casos, os aplicativos requerem a execução de várias operações para resolver um único campo do GraphQL. Com os resolvedores de pipeline, os desenvolvedores agora podem elaborar operações chamadas Funções e executá-las em sequência. Os resolvedores de pipeline são úteis para aplicativos que, por exemplo, exigem a execução de uma verificação de autorização antes de obter dados para um campo.

Um resolvedor de pipeline é composto de um modelo de mapeamento **Anterior**, um modelo de mapeamento **Posterior** e uma lista de Funções. Cada função possui um modelo de mapeamento de **solicitação** e **resposta** que é executado mediante uma fonte de dados. Como um resolvedor de pipeline delega a execução a uma lista de funções, ele não está vinculado a nenhuma fonte de dados. Os resolvedores de unidade e funções que executam a operação mediante fontes de dados são primitivos. Consulte [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.

## Etapa 1: criar um resolvedor de pipeline
<a name="create-a-pipeline-resolver"></a>

No AWS AppSync console, acesse a página **Esquema**.

Salve o seguinte esquema:

```
schema {
    query: Query
    mutation: Mutation
}

type Mutation {
    signUp(input: Signup): User
}

type Query {
    getUser(id: ID!): User
}

input Signup {
    username: String!
    email: String!
}

type User {
    id: ID!
    username: String
    email: AWSEmail
}
```

Vamos conectar um resolvedor de pipeline ao campo **signUp** no tipo **Mutação**. No tipo **Mutação** no lado direito, escolha **Anexar** ao lado do campo de mutação `signUp`. Na página de criação do resolvedor, clique em **Ações** e depois em **Atualizar runtime**. Escolha `Pipeline Resolver` e `VTL` e selecione **Atualizar**. Agora, a página deve mostrar 3 seções, uma área de texto **Modelo de mapeamento anterior**, uma seção **Funções** e uma área de texto **Modelo de mapeamento posterior**.

Nosso resolvedor de pipeline cadastra um usuário validando primeiro a entrada do endereço de e-mail e salvando o usuário no sistema. Vamos encapsular a validação de e-mail dentro de uma função **validateEmail** e salvar o usuário dentro de uma função **saveUser**. A função **validateEmail** é executada primeiro e, se o e-mail for válido, a função **saveUser** será executada.

O fluxo de execução será da seguinte forma:

1. Modelo de mapeamento de solicitação do resolvedor Mutation.signUp

1. Função validateEmail

1. Função saveUser

1. Modelo de mapeamento de resposta do resolvedor Mutation.signUp

Provavelmente reutilizaremos a função **validateEmail** em outros resolvedores em nossa API. Sendo assim, queremos evitar o acesso a `$ctx.args`, já que eles mudarão de um campo do GraphQL para outro. Em vez disso, podemos usar o `$ctx.stash` para armazenar o atributo de e-mail a partir do argumento de campo de entrada `signUp(input: Signup)`.

Modelo de mapeamento **ANTERIOR**:

```
## store email input field into a generic email key
$util.qr($ctx.stash.put("email", $ctx.args.input.email))
{}
```

O console fornece um modelo de mapeamento **POSTERIOR** de passagem padrão que usaremos:

```
$util.toJson($ctx.result)
```

Escolha **Criar** ou **Salvar** para atualizar o resolvedor.

## Etapa 2: criar uma função
<a name="create-a-function"></a>

Na página do resolvedor de pipeline, na seção **Funções**, clique em **Adicionar função** e em **Criar função**. Também é possível criar funções sem passar pela página do resolvedor; para fazer isso, no AWS AppSync console, acesse a página **Funções**. Selecione o botão **Criar função**. Vamos criar uma função que verifique se um e-mail é válido e proveniente de um domínio específico. Se o e-mail não for válido, a função gerará um erro. Caso contrário, ele encaminha qualquer entrada fornecida.

Na página da nova função, escolha **Ações** e, em seguida, **Atualizar runtime**. Escolha `VTL` e, em seguida, **Atualizar**. Crie uma fonte de dados do tipo **NONE**. Escolha a fonte de dados na lista **Nome da fonte de dados**. Em **nome da função**, insira `validateEmail`. Na área **código da função**, substitua tudo por este trecho:

```
#set($valid = $util.matches("^[a-zA-Z0-9_.+-]+@(?:(?:[a-zA-Z0-9-]+\.)?[a-zA-Z]+\.)?(myvaliddomain)\.com", $ctx.stash.email))
#if (!$valid)
    $util.error("$ctx.stash.email is not a valid email.")
#end
{
    "payload": { "email": $util.toJson(${ctx.stash.email}) }
}
```

Cole isso no modelo de mapeamento de resposta:

```
$util.toJson($ctx.result)
```

Verifique suas escolhas e selecione **Criar**. Acabamos de criar nossa função **validateEmail**. Repita essas etapas para criar a função **saveUser** com o código a seguir (a fim de simplificar, usamos a fonte de dados **NONE** e fingimos que o usuário foi salvo no sistema após a execução da função): 

Modelo de mapeamento de solicitação:

```
## $ctx.prev.result contains the signup input values. We could have also
## used $ctx.args.input.
{
    "payload": $util.toJson($ctx.prev.result)
}
```

Modelo de mapeamento da resposta:

```
## an id is required so let's add a unique random identifier to the output
$util.qr($ctx.result.put("id", $util.autoId()))
$util.toJson($ctx.result)
```

Acabamos de criar nossa função **saveUser**.

## Etapa 3: adicionar uma função a um resolvedor de pipeline
<a name="adding-a-function-to-a-pipeline-resolver"></a>

Nossas funções devem ter sido adicionadas automaticamente ao resolvedor de pipeline que acabamos de criar. Se não foi esse o caso ou se você criou as funções por meio da página **Funções**, é possível clicar em **Adicionar função** na página de resolvedor para anexá-las. Adicione as funções **validateEmail** e **saveUser** ao resolvedor. A função **validateEmail** deve ser colocada antes da função **saveUser**. À medida que você adiciona mais funções, pode usar as setas **para cima** e **para baixo** para reorganizar a ordem de execução das funções. Revise suas alterações e escolha **Salvar**.

## Etapa 4: executar uma consulta
<a name="executing-a-query"></a>

No AWS AppSync console, acesse a página **Consultas.** No explorador, verifique se você está usando a mutação. Se não estiver, escolha `Mutation` na lista suspensa e escolha `+`. Digite a consulta a seguir:

```
mutation {
  signUp(input: {
    email: "nadia@myvaliddomain.com"
    username: "nadia"
  }) {
    id
    email
  }
}
```

Ela deve retornar algo semelhante a:

```
{
  "data": {
    "signUp": {
      "id": "256b6cc2-4694-46f4-a55e-8cb14cc5d7fc",
      "email": "nadia@myvaliddomain.com"
    }
  }
}
```

Cadastramos com sucesso nosso usuário e validamos o e-mail de entrada usando um resolvedor de pipeline. Para seguir um tutorial mais completo com foco em resolvedores de pipeline, você pode acessar [Tutorial: Resolvedores de pipeline](tutorial-pipeline-resolvers.md#aws-appsync-tutorial-pipeline-resolvers) 

# Usando uma AWS AppSync API com o AWS CDK
<a name="using-your-api"></a>

**dica**  
[Antes de usar o CDK, recomendamos revisar a [documentação oficial](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html) do CDK junto com AWS AppSync a referência do CDK.](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
Também recomendamos garantir que suas instalações de [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) e [NPM](https://docs.npmjs.com/) estejam funcionando em seu sistema.

Nesta seção, criaremos uma aplicação do CDK simples que pode adicionar e buscar itens de uma tabela do DynamoDB. Esse é um exemplo de início rápido usando parte do código das seções [Projetando seu esquema](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html), [Anexando uma fonte de dados](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html) e [Configurando resolvers](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers-js.html) (). JavaScript

## Configuração de um projeto de CDK
<a name="Setting-up-a-cdk-project"></a>

**Atenção**  
Essas etapas podem não ser totalmente precisas, dependendo do seu ambiente. Presumimos que seu sistema tenha os utilitários necessários instalados, uma forma de interagir com AWS os serviços e as configurações adequadas.

A primeira etapa é instalar o AWS CDK. Na sua CLI, você pode inserir o seguinte comando:

```
npm install -g aws-cdk
```

Depois, você precisa criar um diretório de projeto e navegar até ele. Um exemplo de conjunto de comandos para criar e navegar até um diretório é:

```
mkdir example-cdk-app
cd example-cdk-app
```

Em seguida, você precisa criar um aplicativo. Nosso serviço usa principalmente TypeScript. No diretório do seu projeto, digite o seguinte comando:

```
cdk init app --language typescript
```

Ao fazer isso, um aplicativo CDK junto com seus arquivos de inicialização será instalado:

![\[Terminal output showing Git repository initialization and npm install completion.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-init-app-example.png)


A estrutura do seu projeto pode ser semelhante a esta:

![\[Project directory structure showing folders and files for an example CDK app.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-init-directories.png)


Você notará que temos vários diretórios importantes:
+ `bin`: o arquivo bin inicial criará o aplicativo. Não abordaremos esse tema neste guia.
+ `lib`: o diretório lib contém seus arquivos de pilha. Você pode pensar nos arquivos de pilha como unidades individuais de execução. As estruturas estarão dentro de nossos arquivos de pilha. Basicamente, esses são recursos para um serviço que será ativado CloudFormation quando o aplicativo for implantado. É aqui que a maior parte da nossa codificação acontecerá.
+ `node_modules`: esse diretório é criado pelo NPM e contém todas as dependências de pacotes que você instalou usando o comando do `npm`.

Nosso arquivo de pilha inicial pode conter algo assim:

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
// import * as sqs from 'aws-cdk-lib/aws-sqs';

export class ExampleCdkAppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // The code that defines your stack goes here

    // example resource
    // const queue = new sqs.Queue(this, 'ExampleCdkAppQueue', {
    //   visibilityTimeout: cdk.Duration.seconds(300)
    // });
  }
}
```

Esse é o código clichê para criar uma pilha em nosso aplicativo. A maior parte do nosso código neste exemplo estará dentro do escopo dessa classe.

Para verificar se seu arquivo de pilha está no aplicativo, no diretório do seu aplicativo, execute o seguinte comando no terminal:

```
cdk ls
```

Uma lista de suas pilhas deve aparecer. Caso contrário, talvez seja necessário executar as etapas novamente ou verificar a documentação oficial para obter ajuda.

Se quiser criar suas alterações de código antes da implantação, você sempre pode executar o seguinte comando no terminal:

```
npm run build
```

E para ver as mudanças antes da implantação:

```
cdk diff
```

Antes de adicionarmos nosso código ao arquivo de pilha, vamos realizar um bootstrap. O bootstrapping nos permite provisionar recursos para o CDK antes da implantação do aplicativo. Mais informações sobre esse processo podem ser encontradas [aqui](https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html). Para criar um bootstrap, o comando é:

```
cdk bootstrap aws://ACCOUNT-NUMBER/REGION
```

**dica**  
Essa etapa exige várias permissões do IAM em sua conta. Seu bootstrap será negado se você não as tiver. Se isso acontecer, talvez seja necessário excluir recursos incompletos causados pelo bootstrap, como o bucket S3 que ele gera.

O bootstrap criará vários recursos. A mensagem final terá a aparência a seguir:

![\[Terminal output showing successful bootstrapping of an AWS environment.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-init-bootstrap-final.png)


Como isso é feito uma vez por conta por região, você não precisará fazer com frequência. Os principais recursos do bootstrap são a CloudFormation pilha e o bucket Amazon S3.

O bucket do Amazon S3 é usado para armazenar arquivos e perfis do IAM que concedem as permissões necessárias para realizar implantações. Os recursos necessários são definidos em uma CloudFormation pilha, chamada pilha de bootstrap, que geralmente é nomeada. `CDKToolkit` Como qualquer CloudFormation pilha, ela aparece no CloudFormation console depois de implantada:

![\[CDKToolkit stack with CREATE_COMPLETE status in CloudFormation console.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-init-bootstrap-cfn-console.png)


Isso também se aplica ao bucket:

![\[S3 bucket details showing name, region, access settings, and creation date.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-init-bootstrap-bucket-console.png)


Para importar os serviços que precisamos em nosso arquivo de pilha, podemos usar o seguinte comando:

```
npm install aws-cdk-lib # V2 command
```

**dica**  
Se você estiver tendo problemas com a V2, poderá instalar as bibliotecas individuais usando os comandos da V1:  

```
npm install @aws-cdk/aws-appsync @aws-cdk/aws-dynamodb
```
Não recomendamos isso porque a V1 foi descontinuada.

## Implementação de um projeto de CDK - Esquema
<a name="implementing-a-cdk-project-schema"></a>

Agora podemos começar a implementar nosso código. Primeiro, precisamos criar nosso esquema. Você pode simplesmente criar um arquivo `.graphql` no seu aplicativo:

```
mkdir schema
touch schema.graphql
```

Em nosso exemplo, incluímos um diretório de nível superior chamado `schema` que contém nosso `schema.graphql`:

![\[File structure showing a schema folder containing schema.graphql file.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-code-schema-directory.png)


Dentro do nosso esquema, vamos incluir um exemplo simples:

```
input CreatePostInput {
    title: String
    content: String
}

type Post {
    id: ID!
    title: String
    content: String
}

type Mutation {
    createPost(input: CreatePostInput!): Post
}

type Query {
    getPost: [Post]
}
```

De volta ao nosso arquivo de pilha, precisamos garantir que as seguintes diretivas de importação estejam definidas:

```
import * as cdk from 'aws-cdk-lib';
import * as appsync from 'aws-cdk-lib/aws-appsync';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import { Construct } from 'constructs';
```

Dentro da classe, adicionaremos código para criar nossa API GraphQL e conectá-la ao nosso arquivo `schema.graphql`:

```
export class ExampleCdkAppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    
    // makes a GraphQL API
    const api = new appsync.GraphqlApi(this, 'post-apis', {
      name: 'api-to-process-posts',
      schema: appsync.SchemaFile.fromAsset('schema/schema.graphql'),
    });
  }
}
```

Também adicionaremos alguns códigos para imprimir a URL, a chave de API e a região do GraphQL:

```
export class ExampleCdkAppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    
    // Makes a GraphQL API construct
    const api = new appsync.GraphqlApi(this, 'post-apis', {
      name: 'api-to-process-posts',
      schema: appsync.SchemaFile.fromAsset('schema/schema.graphql'),
    });

    // Prints out URL
    new cdk.CfnOutput(this, "GraphQLAPIURL", {
      value: api.graphqlUrl
    });

    // Prints out the AppSync GraphQL API key to the terminal
    new cdk.CfnOutput(this, "GraphQLAPIKey", {
      value: api.apiKey || ''
    });

    // Prints out the stack region to the terminal
    new cdk.CfnOutput(this, "Stack Region", {
      value: this.region
    });
  }
}
```

Neste momento, usaremos a implantação do nosso aplicativo novamente:

```
cdk deploy
```

Este é o resultado:

![\[Deployment output showing ExampleCdkAppStack details, including GraphQL API URL and stack region.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-code-deploy-schema.png)


Parece que nosso exemplo foi bem-sucedido, mas vamos verificar o AWS AppSync console apenas para confirmar:

![\[GraphQL interface showing successful API request with response data displayed.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-code-deploy-schema-result-1.png)


Parece que nossa API foi criada. Agora, verificaremos o esquema anexado à API:

![\[GraphQL schema defining CreatePostInput, Post type, Mutation, and Query operations.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-code-deploy-schema-result-2.png)


Como parece corresponder ao nosso código de esquema, então foi bem-sucedido. Outra forma de confirmar isso do ponto de vista dos metadados é examinar a pilha: CloudFormation 

![\[CloudFormation stack showing ExampleCdkAppStack update complete and CDKToolkit creation complete.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-code-deploy-schema-result-3.png)


Quando implantamos nosso aplicativo CDK, ele usa recursos como o bootstrap. CloudFormation Cada pilha em nosso aplicativo mapeia 1:1 com uma CloudFormation pilha. Se você voltar ao código da pilha, o nome da pilha foi retirado do nome da classe `ExampleCdkAppStack`. Você pode ver os recursos que ele criou, que também correspondem às nossas convenções de nomenclatura em nossa estrutura da API GraphQL:

![\[Expanded view of post-apis resource showing Schema, DefaultApiKey, and CDKMetadata.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-code-deploy-schema-result-4.png)


## Implementação de um projeto CDK - Fonte de dados
<a name="implementing-a-cdk-project-data-source"></a>

Depois, precisamos adicionar nossa fonte de dados. Nosso exemplo usará uma tabela do DynamoDB. Dentro da classe de pilha, adicionaremos códigos para criar uma tabela:

```
export class ExampleCdkAppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Makes a GraphQL API construct
    const api = new appsync.GraphqlApi(this, 'post-apis', {
      name: 'api-to-process-posts',
      schema: appsync.SchemaFile.fromAsset('schema/schema.graphql'),
    });

    //creates a DDB table
    const add_ddb_table = new dynamodb.Table(this, 'posts-table', {
      partitionKey: {
        name: 'id',
        type: dynamodb.AttributeType.STRING,
      },
    });

    // Prints out URL
    new cdk.CfnOutput(this, "GraphQLAPIURL", {
      value: api.graphqlUrl
    });

    // Prints out the AppSync GraphQL API key to the terminal
    new cdk.CfnOutput(this, "GraphQLAPIKey", {
      value: api.apiKey || ''
    });

    // Prints out the stack region to the terminal
    new cdk.CfnOutput(this, "Stack Region", {
      value: this.region
    });
  }
}
```

Neste momento, vamos implantar novamente:

```
cdk deploy
```

Devemos verificar nossa nova tabela no console do DynamoDB:

![\[DynamoDB console showing ExampleCdkAppStack-poststable as Active with Provisioned capacity.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-code-deploy-ddb-result-1.png)


O nome da nossa pilha está correto e o nome da tabela corresponde ao nosso código. Se verificarmos nossa CloudFormation pilha novamente, agora veremos a nova tabela:

![\[Expanded view of a logical ID in CloudFormation showing post-apis, posts-table, and CDKMetadata.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-code-deploy-ddb-result-2.png)


## Implementação de um projeto de CDK - Resolvedor
<a name="implementing-a-cdk-project-resolver"></a>

Este exemplo usará dois resolvedores: um para consultar a tabela e outro para adicioná-la. Como estamos usando resolvedores de pipeline, precisaremos declarar dois resolvedores de pipeline com uma função em cada um. Na consulta, adicionaremos o seguinte código:

```
export class ExampleCdkAppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Makes a GraphQL API construct
    const api = new appsync.GraphqlApi(this, 'post-apis', {
      name: 'api-to-process-posts',
      schema: appsync.SchemaFile.fromAsset('schema/schema.graphql'),
    });

    //creates a DDB table
    const add_ddb_table = new dynamodb.Table(this, 'posts-table', {
      partitionKey: {
        name: 'id',
        type: dynamodb.AttributeType.STRING,
      },
    });

    // Creates a function for query
    const add_func = new appsync.AppsyncFunction(this, 'func-get-post', {
      name: 'get_posts_func_1',
      api,
      dataSource: api.addDynamoDbDataSource('table-for-posts', add_ddb_table),
      code: appsync.Code.fromInline(`
          export function request(ctx) {
          return { operation: 'Scan' };
          }

          export function response(ctx) {
          return ctx.result.items;
          }
  `),
      runtime: appsync.FunctionRuntime.JS_1_0_0,
    });

    // Creates a function for mutation
    const add_func_2 = new appsync.AppsyncFunction(this, 'func-add-post', {
      name: 'add_posts_func_1',
      api,
      dataSource: api.addDynamoDbDataSource('table-for-posts-2', add_ddb_table),
      code: appsync.Code.fromInline(`
          export function request(ctx) {
            return {
            operation: 'PutItem',
            key: util.dynamodb.toMapValues({id: util.autoId()}),
            attributeValues: util.dynamodb.toMapValues(ctx.args.input),
            };
          }

          export function response(ctx) {
            return ctx.result;
          }
      `),
      runtime: appsync.FunctionRuntime.JS_1_0_0,
    });

    // Adds a pipeline resolver with the get function
    new appsync.Resolver(this, 'pipeline-resolver-get-posts', {
      api,
      typeName: 'Query',
      fieldName: 'getPost',
      code: appsync.Code.fromInline(`
          export function request(ctx) {
          return {};
          }

          export function response(ctx) {
          return ctx.prev.result;
          }
  `),
      runtime: appsync.FunctionRuntime.JS_1_0_0,
      pipelineConfig: [add_func],
    });

    // Adds a pipeline resolver with the create function
    new appsync.Resolver(this, 'pipeline-resolver-create-posts', {
      api,
      typeName: 'Mutation',
      fieldName: 'createPost',
      code: appsync.Code.fromInline(`
          export function request(ctx) {
          return {};
          }

          export function response(ctx) {
          return ctx.prev.result;
          }
  `),
      runtime: appsync.FunctionRuntime.JS_1_0_0,
      pipelineConfig: [add_func_2],
    });

    // Prints out URL
    new cdk.CfnOutput(this, "GraphQLAPIURL", {
      value: api.graphqlUrl
    });

    // Prints out the AppSync GraphQL API key to the terminal
    new cdk.CfnOutput(this, "GraphQLAPIKey", {
      value: api.apiKey || ''
    });

    // Prints out the stack region to the terminal
    new cdk.CfnOutput(this, "Stack Region", {
      value: this.region
    });
  }
}
```

Neste trecho, adicionamos um resolvedor de pipeline chamado `pipeline-resolver-create-posts` com uma função chamada `func-add-post` anexada a ele. Esse é o código que adicionará `Posts` à tabela. O outro resolvedor de pipeline foi chamado `pipeline-resolver-get-posts` com uma função chamada `func-get-post` que recupera `Posts` adicionado à tabela.

Vamos implantar isso para adicioná-lo ao AWS AppSync serviço:

```
cdk deploy
```

Vamos verificar o AWS AppSync console para ver se eles estavam conectados à nossa API GraphQL:

![\[GraphQL API schema showing mutation and query fields with Pipeline resolvers.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-1.png)


Parece estar correto. No código, esses dois resolvedores foram anexados à API GraphQL que criamos (indicada pelo valor de props de `api` presente nos resolvedores e nas funções). Na API GraphQL, os campos aos quais anexamos nossos resolvedores também foram especificados nas props (definidas pelas props `typename` e `fieldname` em cada resolvedor).

Vamos ver se o conteúdo dos resolvedores está correto começando com `pipeline-resolver-get-posts`:

![\[Code snippet showing request and response functions in a resolver, with an arrow pointing to them.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-2.png)


Os manipuladores de antes e depois correspondem ao valor de nossos props `code`. Também podemos ver que uma função chamada `add_posts_func_1` corresponde ao nome da função que anexamos no resolvedor.

Vamos dar uma olhada no conteúdo do código dessa função:

![\[Function code showing request and response methods for a PutItem operation.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-3.png)


Isso corresponde aos props `code` da função `add_posts_func_1`. Como nossa consulta foi enviada com sucesso, vamos verificar a consulta:

![\[Resolver code with request and response functions, and a get_posts_func_1 function listed below.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-4.png)


Eles também correspondem ao código. Se observarmos `get_posts_func_1`:

![\[Code snippet showing two exported functions: request returning 'Scan' operation and response returning items.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-5.png)


Tudo parece estar no lugar certo. Para confirmar isso do ponto de vista dos metadados, podemos verificar nossa pilha no CloudFormation novamente:

![\[List of logical IDs for AWS resources including API, table, functions, and pipelines.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-6.png)


Agora, precisamos testar esse código executando algumas solicitações.

## Implementação de um projeto de CDK - Solicitações
<a name="implementing-a-cdk-project-requests"></a>

Para testar nosso aplicativo no AWS AppSync console, fizemos uma consulta e uma mutação:

![\[GraphQL code snippet showing a query to get post details and a mutation to create a post.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-code-request-1.png)


`MyMutation` contém uma operação `createPost` com os argumentos `1970-01-01T12:30:00.000Z` e `first post`. Retorna `date` e `title` que passamos, bem como o valor `id` gerado automaticamente. Executar a mutação produz o seguinte resultado:

```
{
  "data": {
    "createPost": {
      "date": "1970-01-01T12:30:00.000Z",
      "id": "4dc1c2dd-0aa3-4055-9eca-7c140062ada2",
      "title": "first post"
    }
  }
}
```

Se verificarmos a tabela do DynamoDB rapidamente, poderemos ver nossa entrada na tabela quando a verificarmos:

![\[DynamoDB table entry showing id, date, and title fields for a single item.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/cdk-code-request-2.png)


De volta ao AWS AppSync console, se executarmos a consulta para recuperar isso`Post`, obteremos o seguinte resultado:

```
{
  "data": {
    "getPost": [
      {
        "id": "9f62c4dd-49d5-48d5-b835-143284c72fe0",
        "date": "1970-01-01T12:30:00.000Z",
        "title": "first post"
      }
    ]
  }
}
```

# Usando assinaturas para aplicativos de dados em tempo real no AWS AppSync
<a name="aws-appsync-real-time-data"></a>

**Importante**  
A partir de 13 de março de 2025, você pode criar uma PubSub API em tempo real baseada no WebSockets uso de AWS AppSync Eventos. Para obter mais informações, consulte [Publicar eventos WebSocket](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) no *Guia do desenvolvedor de AWS AppSync eventos*.

AWS AppSyncpermite que você utilize assinaturas para implementar atualizações de aplicativos ao vivo, notificações push etc. Quando os clientes invocam as operações de assinatura do GraphQL, uma conexão WebSocket segura é automaticamente estabelecida e mantida pelo. AWS AppSync Os aplicativos podem então distribuir dados em tempo real de uma fonte de dados para os assinantes, enquanto gerenciam AWS AppSync continuamente os requisitos de conexão e escalabilidade do aplicativo. As seções a seguir mostrarão como as assinaturas funcionam. AWS AppSync

## Diretivas de assinatura do esquema do GraphQL
<a name="graphql-schema-subscription-directives"></a>

As assinaturas em AWS AppSync são invocadas como resposta a uma mutação. Isso significa que você pode criar qualquer fonte de dados em tempo AWS AppSync real especificando uma diretiva do esquema GraphQL em uma mutação.

As bibliotecas de AWS Amplify cliente gerenciam automaticamente o gerenciamento de conexões por assinatura. As bibliotecas usam pure WebSockets como protocolo de rede entre o cliente e o serviço.

**nota**  
Para controlar a autorização no momento da conexão com uma assinatura, você pode usar AWS Identity and Access Management (IAM) AWS Lambda, grupos de identidade do Amazon Cognito ou grupos de usuários do Amazon Cognito para autorização em nível de campo. Para controles de acesso refinados em assinaturas, você pode anexar resolvedores aos seus campos de assinatura e executar a lógica usando a identidade do chamador e das fontes de dados. AWS AppSync Para obter mais informações, consulte [Configurando autorização e autenticação para proteger seu GraphQL APIs](security-authz.md).

As assinaturas são acionadas a partir de mutações e o conjunto de seleção da mutação é enviado aos assinantes.

O exemplo a seguir mostra como trabalhar com assinaturas do GraphQL. Ele não especifica uma fonte de dados porque a fonte de dados pode ser Lambda, Amazon DynamoDB ou Amazon Service. OpenSearch 

Para começar a usar assinaturas, é necessário adicionar um ponto de entrada de assinatura ao esquema, da seguinte forma:

```
schema {
    query: Query
    mutation: Mutation
    subscription: Subscription
}
```

Digamos que você tenha um site de postagens de blog e deseje assinar novos blogs e alterações aos blogs existentes. Para fazer isso, adicione a seguinte definição `Subscription` ao esquema:

```
type Subscription {
    addedPost: Post
    updatedPost: Post
    deletedPost: Post
}
```

Digamos também que possui as seguintes mutações:

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

Você pode tornar esses campos em tempo real ao adicionar uma diretiva `@aws_subscribe(mutations: ["mutation_field_1", "mutation_field_2"])` para cada uma das assinaturas sobre as quais deseja receber notificações, da seguinte forma:

```
type Subscription {
    addedPost: Post
    @aws_subscribe(mutations: ["addPost"])
    updatedPost: Post
    @aws_subscribe(mutations: ["updatePost"])
    deletedPost: Post
    @aws_subscribe(mutations: ["deletePost"])
}
```

Como a `@aws_subscribe(mutations: ["",..,""])` recebe uma matriz de entradas de mutação, você pode especificar diversas mutações, que iniciam uma assinatura. Se estiver assinando a partir de um cliente, a consulta do GraphQL poderá ser semelhante ao seguinte:

```
subscription NewPostSub {
    addedPost {
        __typename
        version
        title
        content
        author
        url
    }
}
```

A consulta de assinatura é necessária para conexões de cliente e ferramentas.

Com o WebSockets cliente puro, a filtragem do conjunto de seleção é feita por cliente, pois cada cliente pode definir seu próprio conjunto de seleção. Nesse caso, o conjunto de seleção da assinatura deve ser um subconjunto do conjunto de seleção da mutação. Por exemplo, uma assinatura `addedPost{author title}` vinculada à mutação `addPost(...){id author title url version}` recebe somente o autor e o título da postagem. Ela não recebe os outros campos. No entanto, se a mutação não tivesse o autor no conjunto de seleção, o assinante obteria um valor `null` para o campo autor (ou um erro, caso o campo de autor fosse definido como necessário/não nulo no esquema).

O conjunto de seleção de assinatura é essencial ao usar o pure WebSockets. Se um campo não estiver definido explicitamente na assinatura, AWS AppSync ele não retornará.

No exemplo anterior, as assinaturas não tinham argumentos. Digamos que o seu esquema tenha a seguinte aparência:

```
type Subscription {
    updatedPost(id:ID! author:String): Post
    @aws_subscribe(mutations: ["updatePost"])
}
```

Nesse caso, o cliente define uma assinatura da seguinte forma:

```
subscription UpdatedPostSub {
    updatedPost(id:"XYZ", author:"ABC") {
        title
        content
    }
}
```

O tipo de retorno de um campo do `subscription` no esquema deve corresponder ao tipo de retorno do campo de mutação correspondente. No exemplo anterior, isso foi mostrado como `addPost` e `addedPost` retornados como um tipo de `Post`.

Para configurar assinaturas no cliente, consulte [Como criar um aplicativo cliente usando o cliente Amplify](building-a-client-app.md).

## Usar argumentos de assinatura
<a name="using-subscription-arguments"></a>

Uma parte importante do uso de assinaturas do GraphQL é entender quando e como usar argumentos. Você pode fazer alterações sutis para modificar como e quando notificar os clientes sobre as mutações que ocorreram. Para fazer isso, consulte o esquema de amostra do capítulo de início rápido, que cria "Todos". Para este exemplo de esquema, são definidas as seguintes mutações:

```
type Mutation {
    createTodo(input: CreateTodoInput!): Todo
    updateTodo(input: UpdateTodoInput!): Todo
    deleteTodo(input: DeleteTodoInput!): Todo
}
```

No exemplo padrão, os clientes podem assinar atualizações de qualquer `Todo` usando o `onUpdateTodo` `subscription` sem argumentos:

```
subscription OnUpdateTodo {
  onUpdateTodo {
    description
    id
    name
    when
  }
}
```

Você pode filtrar seu `subscription` usando seus argumentos. Por exemplo, para acionar somente um `subscription` quando um `todo` com um `ID` específico for atualizado, especifique o valor de `ID`:

```
subscription OnUpdateTodo {
  onUpdateTodo(id: "a-todo-id") {
    description
    id
    name
    when
  }
}
```

Você também pode enviar vários argumentos. Por exemplo, o seguinte `subscription` demonstra como receber notificações sobre qualquer atualização do `Todo` em um local e horário específicos:

```
subscription todosAtHome {
  onUpdateTodo(when: "tomorrow", where: "at home") {
    description
    id
    name
    when
    where
  }
}
```

Observe que todos os argumentos são opcionais. Se você não especificar nenhum argumento em seu `subscription`, será inscrito em todas as atualizações do `Todo` que ocorrerem em seu aplicativo. No entanto, você pode atualizar sua definição do campo do `subscription` para exigir o argumento do `ID`. Isso forçaria a resposta de um `todo` específico em vez de todos os `todo`s:

```
onUpdateTodo(
  id: ID!,
  name: String,
  when: String,
  where: String,
  description: String
): Todo
```

### Valor de argumento nulo tem significado
<a name="argument-null-value-has-meaning"></a>

Ao fazer uma consulta de assinatura AWS AppSync, um valor de `null` argumento filtrará os resultados de forma diferente de omitir totalmente o argumento.

Vamos voltar ao exemplo da API todos, onde poderíamos criar todos. Veja o esquema de amostra no capítulo de início rápido.

Vamos modificar nosso esquema para incluir um novo campo de `owner`, no tipo `Todo`, descrevendo quem é o proprietário. O campo de `owner` não é obrigatório e só pode ser ativado em `UpdateTodoInput`. Veja a seguinte versão simplificada do esquema:

```
type Todo {
  id: ID!
  name: String!
  when: String!
  where: String!
  description: String!
  owner: String
}

input CreateTodoInput {
  name: String!
  when: String!
  where: String!
  description: String!
}

input UpdateTodoInput {
  id: ID!
  name: String
  when: String
  where: String
  description: String
  owner: String
}

type Subscription {
    onUpdateTodo(
        id: ID,
        name: String,
        when: String,
        where: String,
        description: String
    ): Todo @aws_subscribe(mutations: ["updateTodo"])
}
```

A assinatura a seguir retorna todas as atualizações de `Todo`:

```
subscription MySubscription {
  onUpdateTodo {
    description
    id
    name
    when
    where
  }
}
```

Se você modificar a assinatura anterior para adicionar o argumento do campo `owner: null`, estará fazendo uma pergunta diferente. Essa assinatura agora registra o cliente para ser notificado sobre todas as atualizações de `Todo` que não foram fornecidas a um proprietário.

```
subscription MySubscription {
  onUpdateTodo(owner: null) {
    description
    id
    name
    when
    where
  }
}
```

**nota**  
**A partir de 1º de janeiro de 2022, o MQTT over não WebSockets está mais disponível como protocolo para assinaturas do GraphQL no. AWS AppSync APIs O Pure WebSockets é o único protocolo compatível com AWS AppSync.**  
Clientes baseados no AWS AppSync SDK ou nas bibliotecas do Amplify, lançados após novembro de 2019, usam automaticamente o WebSockets pure por padrão. Atualizar os clientes para a versão mais recente permite que eles usem AWS AppSync o WebSockets motor puro.  
O Pure WebSockets vem com um tamanho de carga útil maior (240 KB), uma variedade maior de opções de clientes e CloudWatch métricas aprimoradas. Para obter mais informações sobre o uso de WebSocket clientes puros, consulte[Construindo um WebSocket cliente em tempo real em AWS AppSync](real-time-websocket-client.md).

# Criação de genéricos pub/sub APIs com tecnologia sem servidor em WebSockets AWS AppSync
<a name="aws-appsync-real-time-create-generic-api-serverless-websocket"></a>

**Importante**  
A partir de 13 de março de 2025, você pode criar uma PubSub API em tempo real baseada no WebSockets uso de AWS AppSync Eventos. Para obter mais informações, consulte [Publicar eventos WebSocket](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) no *Guia do desenvolvedor de AWS AppSync eventos*.

Alguns aplicativos exigem apenas WebSocket APIs que os clientes ouçam um canal ou tópico específico. Dados JSON genéricos sem formato específico ou requisitos fortemente informados podem ser enviados a clientes que recebem um desses canais em um padrão puro e simples de publicação-assinatura (pub/sub).

Use AWS AppSync para implementar algo simples pub/sub WebSocket APIs com pouco ou nenhum conhecimento em GraphQL em minutos, gerando automaticamente o código GraphQL no back-end da API e no lado do cliente.

## Crie e configure o pub-sub APIs
<a name="aws-appsync-real-time-enhanced-filtering-using-pub-sub-apis"></a>

Para começar, faça o seguinte: 

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

   1. No **Painel**, escolha **Criar API**.

1. Na próxima tela, escolha **Criar uma API em tempo real** e, em seguida, escolha **Avançar**.

1. Insira um nome amigável para sua pub/sub API.

1. Você pode ativar os atributos da [API privada](https://docs.aws.amazon.com/appsync/latest/devguide/using-private-apis.html), mas recomendamos mantê-los desativados por enquanto. Escolha **Próximo**.

1. Você pode optar por gerar automaticamente uma pub/sub API funcional usando WebSockets o. Também recomendamos desativar esse atributo por enquanto. Escolha **Próximo**.

1. Escolha **Criar API** e aguarde alguns minutos. Uma nova API AWS AppSync pub/sub pré-configurada será criada em sua conta. AWS 

A API usa AWS AppSync os resolvedores locais integrados (para obter mais informações sobre o uso de resolvedores locais, consulte o [Tutorial: Resolvers locais](https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-local-resolvers-js.html) no *Guia do AWS AppSync desenvolvedor*) para gerenciar vários pub/sub canais e WebSocket conexões temporários, o que entrega e filtra automaticamente os dados aos clientes inscritos com base apenas no nome do canal. As chamadas de API são autorizadas com uma chave da API.

Depois que a API for implantada, você verá algumas etapas extras para gerar o código do cliente e integrá-lo ao aplicativo cliente. Para obter um exemplo de como integrar rapidamente um cliente, este guia usará um aplicativo web React simples.

1. Comece criando um aplicativo React padronizado usando o [NPM](https://www.npmjs.com/get-npm) na máquina local:

   ```
   $ npx create-react-app mypubsub-app 
   $ cd mypubsub-app
   ```
**nota**  
Este exemplo usa as [bibliotecas do Amplify](https://docs.amplify.aws/lib/) para conectar clientes à API de back-end. No entanto, não é necessário criar um projeto Amplify CLI localmente. Embora o React seja o cliente preferido neste exemplo, as bibliotecas do Amplify também oferecem suporte a clientes iOS, Android e Flutter, fornecendo os mesmos recursos nesses diferentes runtimes. [Os clientes Amplify suportados fornecem abstrações simples para interagir com os back-ends da API AWS AppSync GraphQL com poucas linhas de código, incluindo WebSocket recursos integrados totalmente compatíveis com o protocolo em tempo real:AWS AppSync WebSocket ](https://docs.aws.amazon.com/appsync/latest/devguide/real-time-websocket-client.html)  

   ```
   $ npm install @aws-amplify/api
   ```

1. No AWS AppSync console, selecione e, em seguida **JavaScript**, **Baixe para baixar** um único arquivo com os detalhes de configuração da API e o código de operações do GraphQL gerado.

1. Copie o arquivo baixado para a pasta do `/src` no projeto do React.

1. Em seguida, substitua o conteúdo do arquivo padrão existente do `src/App.js` pelo código de cliente de amostra disponível no console.

1. Use o seguinte comando para criar e iniciar o aplicativo localmente.

   ```
   $ npm start
   ```

1. Para testar o envio e o recebimento de dados em tempo real, abra duas janelas do navegador e acesse*localhost:3000*. O aplicativo de amostra está configurado para enviar dados JSON genéricos para um canal codificado chamado. *robots*

1.  Em uma das janelas do navegador, insira o seguinte blob JSON na caixa de texto e clique em **Enviar**: 

   ```
   {
     "robot":"r2d2",
     "planet": "tatooine"
   }
   ```

Ambas as instâncias do navegador são inscritas no *robots* canal e recebem os dados publicados em tempo real, exibidos na parte inferior do aplicativo web:

![\[Exemplo de aplicativo React para pub/sub API\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/pub-sub-react.png)


Todo o código necessário da API GraphQL, incluindo o esquema, os resolvedores e as operações, é gerado automaticamente para permitir um caso de uso genérico. pub/sub No back-end, os dados são publicados no endpoint em tempo real com uma mutação AWS AppSync do GraphQL, como a seguinte:

```
mutation PublishData {
    publish(data: "{\"msg\": \"hello world!\"}", name: "channel") {
        data
        name
    }
}
```

Os assinantes acessam os dados publicados enviados para o canal temporário específico com uma assinatura relacionada do GraphQL:

```
subscription SubscribeToData {
    subscribe(name:"channel") {
        name
        data
    }
}
```

## Implementando o pub-sub APIs em aplicativos existentes
<a name="aws-appsync-real-time-enhanced-filtering-existing-apps"></a>

Caso você só precise implementar um recurso em tempo real em um aplicativo existente, essa configuração genérica de pub/sub API pode ser facilmente integrada a qualquer aplicativo ou tecnologia de API. Embora haja vantagens em usar um único endpoint de API para acessar, manipular e combinar com segurança dados de uma ou mais fontes de dados em uma única chamada de rede com o GraphQL, não há necessidade de converter ou reconstruir um aplicativo existente baseado em REST do zero para aproveitar os recursos em tempo real do GraphQL. AWS AppSync Por exemplo, você pode ter uma carga de trabalho CRUD existente em um endpoint de API separado com clientes enviando e recebendo mensagens ou eventos do aplicativo existente para a pub/sub API genérica somente para fins e pub/sub em tempo real. 

# Definindo filtros de assinaturas aprimorados em AWS AppSync
<a name="aws-appsync-real-time-enhanced-filtering"></a>

**Importante**  
A partir de 13 de março de 2025, você pode criar uma PubSub API em tempo real baseada no WebSockets uso de AWS AppSync Eventos. Para obter mais informações, consulte [Publicar eventos WebSocket](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) no *Guia do desenvolvedor de AWS AppSync eventos*.

Em AWS AppSync, você pode definir e habilitar a lógica de negócios para filtragem de dados no back-end diretamente nos resolvedores de assinatura da API GraphQL usando filtros que suportam operadores lógicos adicionais. Você pode configurar esses filtros, diferentemente dos argumentos de assinatura definidos na consulta de assinatura no cliente. Para obter mais informações sobre como usar argumentos de assinatura, consulte [Usar argumentos de assinatura](aws-appsync-real-time-data.md#using-subscription-arguments). Para obter uma lista de operadores, consulte [AWS AppSync referência do utilitário do modelo de mapeamento do resolvedor](resolver-util-reference.md).

Para os fins deste documento, dividimos a filtragem de dados em tempo real nas seguintes categorias:
+ **Filtragem básica:** filtragem com base nos argumentos definidos pelo cliente na consulta de assinatura.
+ **Filtragem aprimorada** - Filtragem baseada na lógica definida centralmente no back-end do AWS AppSync serviço.

As seções a seguir explicam como configurar filtros de assinatura avançados e mostrar seu uso prático.

## Definir assinaturas no esquema do GraphQL
<a name="aws-appsync-real-time-enhanced-filtering-using-subscription-filters"></a>

Para usar filtros de assinatura avançados, defina a assinatura no esquema do GraphQL e, em seguida, defina o filtro avançado usando uma extensão de filtragem. Para ilustrar como a filtragem aprimorada de assinaturas funciona AWS AppSync, use o seguinte esquema do GraphQL, que define uma API do sistema de gerenciamento de tickets, como exemplo:

```
type Ticket {
	id: ID
	createdAt: AWSDateTime
	content: String
	severity: Int
	priority: Priority
	category: String
	group: String
	status: String
	
}

type Mutation {
	createTicket(input: TicketInput): Ticket
}

type Query {
	getTicket(id: ID!): Ticket
}

type Subscription {
	onSpecialTicketCreated: Ticket @aws_subscribe(mutations: ["createTicket"])
	onGroupTicketCreated(group: String!): Ticket @aws_subscribe(mutations: ["createTicket"])
}



enum Priority {
	none
	lowest
	low
	medium
	high
	highest
}

input TicketInput {
	content: String
	severity: Int
	priority: Priority
	category: String
	group: String
```

Suponha que você crie uma fonte de dados do `NONE` para a API e, em seguida, anexe um resolvedor à mutação do `createTicket` usando essa fonte de dados. Os manipuladores podem ser semelhantes a estes:

```
import { util } from '@aws-appsync/utils';

export function request(ctx) {
	return {
		payload: {
			id: util.autoId(),
			createdAt: util.time.nowISO8601(),
			status: 'pending',
			...ctx.args.input,
		},
	};
}

export function response(ctx) {
	return ctx.result;
}
```

**nota**  
Filtros aprimorados são habilitados no manipulador do resolvedor do GraphQL em uma determinada assinatura. Para obter mais informações, consulte a [Referência do resolvedor](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html).

Para implementar o comportamento do filtro aprimorado, você deve usar a função `extensions.setSubscriptionFilter()` para definir uma expressão de filtro avaliada em relação aos dados publicados de uma mutação do GraphQL na qual os clientes inscritos possam estar interessados. Para ter mais informações sobre as extensões de filtragem, consulte [Extensões](https://docs.aws.amazon.com//appsync/latest/devguide/extensions-js.html).

A seção a seguir explica como usar extensões de filtragem para implementar filtros avançados.

## Criar filtros avançados de assinatura usando extensões de filtragem
<a name="aws-appsync-real-time-enhanced-filtering-defining-filters"></a>

Os filtros avançados são escritos em JSON no manipulador de respostas dos resolvedores da assinatura. Os filtros podem ser agrupados em uma lista chamada `filterGroup`. Os filtros são definidos usando pelo menos uma regra, cada uma com campos, operadores e valores. Vamos definir um novo resolvedor para `onSpecialTicketCreated` que configura um filtro avançado. Você pode configurar várias regras em um filtro que são avaliadas usando a lógica AND, enquanto vários filtros em um grupo de filtros são avaliados usando a lógica OR:

```
import { util, extensions } from '@aws-appsync/utils';

export function request(ctx) {
	// simplfy return null for the payload
	return { payload: null };
}

export function response(ctx) {
	const filter = {
		or: [
			{ severity: { ge: 7 }, priority: { in: ['high', 'medium'] } },
			{ category: { eq: 'security' }, group: { in: ['admin', 'operators'] } },
		],
	};
	extensions.setSubscriptionFilter(util.transform.toSubscriptionFilter(filter));

  // important: return null in the response
	return null;
}
```

Com base nos filtros definidos no exemplo anterior, tíquetes importantes serão automaticamente enviados para clientes da API inscritos se um tíquete for criado com:
+ nível de `priority` `high` ou `medium`

  E 
+ nível de `severity` maior ou igual a `7` (`ge`)

OU 
+ `classification`bilhete definido como `Security` 

  E 
+ atribuição de `group` definida como `admin` ou `operators`

![\[Exemplo mostrando uma consulta de filtragem de tíquetes\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/aws-priority-example.png)


Os filtros definidos no resolvedor de assinaturas (filtragem avançada) têm precedência sobre a filtragem baseada somente nos argumentos da assinatura (filtragem básica). Para obter mais informações sobre como usar argumentos de assinatura, consulte [Usar argumentos de assinatura](https://docs.aws.amazon.com//appsync/latest/devguide/aws-appsync-real-time-data.html#using-subscription-arguments)).

Se um argumento for definido e exigido no esquema GraphQL da assinatura, a filtragem com base no argumento fornecido ocorrerá somente se o argumento for definido como uma regra no método `extensions.setSubscriptionFilter()` do resolvedor. No entanto, se não houver métodos de filtragem de `extensions` no resolvedor de assinaturas, os argumentos definidos no cliente serão usados somente para a filtragem básica. Não é possível usar a filtragem básica e a filtragem avançada ao mesmo tempo.

Você pode usar a [variável de `context`](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html) na lógica de extensão de filtro da assinatura para acessar informações contextuais sobre a solicitação. Por exemplo, ao usar grupos de usuários do Amazon Cognito, OIDC ou autorizadores personalizados de Lambda para autorização, você pode recuperar informações sobre os usuários no `context.identity` quando a assinatura é estabelecida. Você pode usar essas informações para estabelecer filtros com base na identidade dos seus usuários.

Agora, suponha que você queira implementar o comportamento de filtro avançado para `onGroupTicketCreated`. A assinatura do `onGroupTicketCreated` exige um nome de `group` obrigatório como argumento. Quando criados, os tickets recebem automaticamente um status `pending`. Você pode configurar um filtro de assinatura para receber somente tickets recém-criados que pertencem ao grupo fornecido:

```
import { util, extensions } from '@aws-appsync/utils';

export function request(ctx) {
	// simplfy return null for the payload
	return { payload: null };
}

export function response(ctx) {
	const filter = { group: { eq: ctx.args.group }, status: { eq: 'pending' } };
	extensions.setSubscriptionFilter(util.transform.toSubscriptionFilter(filter));

	return null;
}
```

Quando os dados são publicados usando uma mutação, como no exemplo a seguir:

```
mutation CreateTicket {
  createTicket(input: {priority: medium, severity: 2, group: "aws"}) {
    id
    priority
    severity
    status
    group
    createdAt
  }
}
```

Os clientes inscritos ouvem os dados a serem enviados automaticamente WebSockets assim que um ticket é criado com a `createTicket` mutação:

```
subscription OnGroup {
  onGroupTicketCreated(group: "aws") {
    category
    status
    severity
    priority
    id
    group
    createdAt
    content
  }
}
```

Os clientes podem ser inscritos sem argumentos porque a lógica de filtragem é implementada no AWS AppSync serviço com filtragem aprimorada, o que simplifica o código do cliente. Os clientes receberão dados somente se os critérios de filtro definidos forem atendidos.

## Definição de filtros aprimorados para campos de esquema aninhados
<a name="aws-appsync-real-time-enhanced-filters-nested-schema-fields.title"></a>

Você pode usar a filtragem de assinatura avançada para filtrar campos de esquema aninhados. Suponha que tenhamos modificado o esquema da seção anterior para incluir tipos de localização e endereço:

```
type Ticket {
	id: ID
	createdAt: AWSDateTime
	content: String
	severity: Int
	priority: Priority
	category: String
	group: String
	status: String
	location: ProblemLocation
}

type Mutation {
	createTicket(input: TicketInput): Ticket
}

type Query {
	getTicket(id: ID!): Ticket
}

type Subscription {
	onSpecialTicketCreated: Ticket @aws_subscribe(mutations: ["createTicket"])
	onGroupTicketCreated(group: String!): Ticket @aws_subscribe(mutations: ["createTicket"])
}

type ProblemLocation {
	address: Address
}

type Address {
	country: String
}

enum Priority {
	none
	lowest
	low
	medium
	high
	highest
}

input TicketInput {
	content: String
	severity: Int
	priority: Priority
	category: String
	group: String
	location: AWSJSON
```

Com esse esquema, você pode usar um separador `.` para representar o aninhamento. O exemplo a seguir adiciona uma regra de filtro para um campo de esquema aninhado em `location.address.country`. A assinatura será acionada se o endereço do tíquete estiver definido como `USA`:

```
import { util, extensions } from '@aws-appsync/utils';

export const request = (ctx) => ({ payload: null });

export function response(ctx) {
	const filter = {
		or: [
			{ severity: { ge: 7 }, priority: { in: ['high', 'medium'] } },
			{ category: { eq: 'security' }, group: { in: ['admin', 'operators'] } },
			{ 'location.address.country': { eq: 'USA' } },
		],
	};
	extensions.setSubscriptionFilter(util.transform.toSubscriptionFilter(filter));
	return null;
}
```

No exemplo acima, `location` representa o nível de aninhamento um, `address` representa o nível de aninhamento dois e `country` representa o nível de aninhamento três, todos separados pelo separador `.`.

Você pode testar essa assinatura usando a mutação `createTicket`:

```
mutation CreateTicketInUSA {
  createTicket(input: {location: "{\"address\":{\"country\":\"USA\"}}"}) {
    category
    content
    createdAt
    group
    id
    location {
      address {
        country
      }
    }
    priority
    severity
    status
  }
}
```

## Definindo filtros avançados do cliente
<a name="aws-appsync-real-time-enhanced-filtering-defining-from-client"></a>

Você pode usar a filtragem básica no GraphQL com [argumentos de assinaturas](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-data.html#using-subscription-arguments). O cliente que faz a chamada na consulta de assinatura define os valores dos argumentos. Quando filtros aprimorados são habilitados em um resolvedor de AWS AppSync assinatura com a `extensions` filtragem, os filtros de back-end definidos no resolvedor têm precedência e prioridade.

Configure filtros aprimorados dinâmicos definidos pelo cliente usando um argumento `filter` na assinatura. Ao configurar esses filtros, você deve atualizar o esquema do GraphQL para refletir o novo argumento:

```
...
type Subscription {
    onSpecialTicketCreated(filter: String): Ticket
        @aws_subscribe(mutations: ["createTicket"])
}
...
```

O cliente pode então enviar uma consulta de assinatura, como no exemplo a seguir:

```
subscription onSpecialTicketCreated($filter: String) {
     onSpecialTicketCreated(filter: $filter) {
        id
        group
        description
        priority
        severity
     }
 }
```

Você pode configurar a variável de consulta como no exemplo a seguir:

```
{"filter" : "{\"severity\":{\"le\":2}}"}
```

O utilitário do resolvedor `util.transform.toSubscriptionFilter()` pode ser implementado no modelo de mapeamento de resposta da assinatura para aplicar o filtro definido no argumento da assinatura para cada cliente:

```
import { util, extensions } from '@aws-appsync/utils';

export function request(ctx) {
	// simplfy return null for the payload
	return { payload: null };
}

export function response(ctx) {
	const filter = ctx.args.filter;
	extensions.setSubscriptionFilter(util.transform.toSubscriptionFilter(filter));
	return null;
}
```

Com essa estratégia, os clientes podem definir seus próprios filtros que usam lógica de filtragem avançada e operadores adicionais. Os filtros são atribuídos quando um determinado cliente invoca a consulta de assinatura em uma conexão segura WebSocket . Para obter mais informações sobre o utilitário de transformação para filtragem aprimorada, incluindo o formato da carga útil da variável de `filter` consulta, consulte a visão geral dos [JavaScriptresolvedores](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html).

## Restrições adicionais de filtragem avançada
<a name="aws-appsync-real-time-enhanced-filtering-additional-restrictions"></a>

Veja abaixo vários casos de uso em que restrições adicionais são colocadas em filtros avançados:
+ Os filtros avançados não oferecem suporte à filtragem de listas de objetos de nível superior. Nesse caso de uso, os dados publicados da mutação serão ignorados para assinaturas aprimoradas.
+ AWS AppSync suporta até cinco níveis de aninhamento. Os filtros nos campos do esquema após o nível cinco de aninhamento serão ignorados. Veja a resposta do GraphQL abaixo. O campo `continent` em `venue.address.country.metadata.continent` é permitido porque é um ninho de nível cinco. No entanto, `financial` em `venue.address.country.metadata.capital.financial` é um ninho de nível seis, então o filtro não funcionará:

  ```
  {
      "data": {
          "onCreateFilterEvent": {
              "venue": {
                  "address": {
                      "country": {
                          "metadata": {
                              "capital": {
                                  "financial": "New York"
                              },
                              "continent" : "North America"
                          }
                      },
                      "state": "WA"
                  },
                  "builtYear": 2023
              },
              "private": false,
          }
      }
  }
  ```

# Cancelando a assinatura de WebSocket conexões usando filtros no AWS AppSync
<a name="aws-appsync-real-time-invalidation"></a>

**Importante**  
A partir de 13 de março de 2025, você pode criar uma PubSub API em tempo real baseada no WebSockets uso de AWS AppSync Eventos. Para obter mais informações, consulte [Publicar eventos WebSocket](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) no *Guia do desenvolvedor de AWS AppSync eventos*.

Em AWS AppSync, você pode cancelar a assinatura à força e fechar (invalidar) uma WebSocket conexão de um cliente conectado com base em uma lógica de filtragem específica. Isso será útil em cenários relacionados à autorização, como quando você remove um usuário de um grupo.

A invalidação da assinatura ocorre em resposta a uma carga definida em uma mutação. Recomendamos que você trate as mutações usadas para invalidar conexões de assinatura como operações administrativas em sua API e permissões de escopo de modo adequado, limitando o uso a um usuário administrador, grupo ou serviço de back-end. Por exemplo, usando diretivas de autorização de esquema, como `@aws_auth(cognito_groups: ["Administrators"])` ou `@aws_iam`. Para obter mais informações, consulte [Usar modos de autorização adicionais](https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html#using-additional-authorization-modes).

Os filtros de invalidação usam a mesma sintaxe e lógica dos [filtros de assinatura aprimorados](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-enhanced-filtering.html). Defina esses filtros usando os seguintes utilitários:
+ `extensions.invalidateSubscriptions()` — Definido no manipulador de resposta do resolvedor do GraphQL para uma mutação.
+ `extensions.setSubscriptionInvalidationFilter()` — Definido no manipulador de resposta do resolvedor do GraphQL das assinaturas vinculadas à mutação.

Para obter mais informações sobre extensões de filtragem de invalidação, consulte a visão geral dos [JavaScriptresolvedores](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html).

## Usar a invalidação da assinatura
<a name="aws-appsync-real-time-invalidation-using-invalidations"></a>

Para ver como funciona a invalidação de assinatura AWS AppSync, use o seguinte esquema do GraphQL:

```
type User {
  userId: ID!
  groupId: ID!
}
    
type Group {
  groupId: ID!
  name: String!
  members: [ID!]!
}

type GroupMessage {
  userId: ID!
  groupId: ID!
  message: String!
}

type Mutation {
    createGroupMessage(userId: ID!, groupId : ID!, message: String!): GroupMessage
    removeUserFromGroup(userId: ID!, groupId : ID!) : User @aws_iam
}

type Subscription {
    onGroupMessageCreated(userId: ID!, groupId : ID!): GroupMessage
        @aws_subscribe(mutations: ["createGroupMessage"])
}

type Query {
	none: String
}
```

Defina um filtro de invalidação no código do resolvedor de mutação `removeUserFromGroup`:

```
import { extensions } from '@aws-appsync/utils';

export function request(ctx) {
	return { payload: null };
}

export function response(ctx) {
	const { userId, groupId } = ctx.args;
	extensions.invalidateSubscriptions({
		subscriptionField: 'onGroupMessageCreated',
		payload: { userId, groupId },
	});
	return { userId, groupId };
}
```

Quando a mutação é invocada, os dados definidos no objeto `payload` são usados para cancelar a assinatura definida em `subscriptionField`. Um filtro de invalidação também é definido no modelo de mapeamento de resposta da assinatura do `onGroupMessageCreated`. 

Se a `extensions.invalidateSubscriptions()` carga contiver uma ID que corresponda à IDs do cliente inscrito, conforme definido no filtro, a assinatura correspondente será cancelada. Além disso, a WebSocket conexão está fechada. Defina o código do resolvedor de assinatura para a assinatura `onGroupMessageCreated`:

```
import { util, extensions } from '@aws-appsync/utils';

export function request(ctx) {
	// simplfy return null for the payload
	return { payload: null };
}

export function response(ctx) {
	const filter = { groupId: { eq: ctx.args.groupId } };
	extensions.setSubscriptionFilter(util.transform.toSubscriptionFilter(filter));

	const invalidation = { groupId: { eq: ctx.args.groupId }, userId: { eq: ctx.args.userId } };
	extensions.setSubscriptionInvalidationFilter(util.transform.toSubscriptionFilter(invalidation));

	return null;
}
```

Observe que o gerenciador de respostas da assinatura pode ter filtros de assinatura e filtros de invalidação definidos ao mesmo tempo.

Por exemplo, suponha que o cliente A inscreva um novo usuário com o ID `user-1` no grupo com o ID `group-1` usando a seguinte solicitação de assinatura:

```
onGroupMessageCreated(userId : "user-1", groupId: :"group-1"){...}
```

AWS AppSync executa o resolvedor de assinaturas, que gera filtros de assinatura e invalidação conforme definido no modelo de mapeamento de `onGroupMessageCreated` resposta anterior. Para o cliente A, os filtros de assinatura permitem que os dados sejam enviados somente para `group-1`, e os filtros de invalidação são definidos para `user-1` e `group-1`.

Agora suponha que o cliente B inscreva um usuário com o ID `user-2` no grupo com o ID `group-2` usando a seguinte solicitação de assinatura:

```
onGroupMessageCreated(userId : "user-2", groupId: :"group-2"){...}
```

AWS AppSync executa o resolvedor de assinaturas, que gera filtros de assinatura e invalidação. Para o cliente B, os filtros de assinatura permitem que os dados sejam enviados somente para `group-2`, e os filtros de invalidação são definidos para `user-2` e `group-2`.

Em seguida, suponha que uma nova mensagem de grupo com o ID `message-1` seja criada usando uma solicitação de mutação, como no exemplo a seguir:

```
createGroupMessage(id: "message-1", groupId :
      "group-1", message: "test message"){...}
```

Os clientes inscritos que correspondem aos filtros definidos recebem automaticamente a seguinte carga de dados por meio de: WebSockets

```
{
  "data": {
    "onGroupMessageCreated": {
      "id": "message-1",
      "groupId": "group-1",
      "message": "test message",
    }
  }
}
```

O cliente A recebe a mensagem porque os critérios de filtragem correspondem ao filtro de assinatura definido. No entanto, o cliente B não recebe a mensagem, pois o usuário não faz parte de `group-1`. Além disso, a solicitação não corresponde ao filtro de assinatura definido no resolvedor de assinatura.

Por fim, suponha que `user-1` seja removido de `group-1` usando a seguinte solicitação de mutação:

```
removeUserFromGroup(userId: "user-1", groupId : "group-1"){...}
```

A mutação inicia uma invalidação de assinatura, conforme definido no código do manipulador de respostas do `extensions.invalidateSubscriptions()` resolvedor. AWS AppSync em seguida, cancela a assinatura do cliente A e fecha sua conexão. WebSocket O cliente B não é afetado, pois a carga de invalidação definida na mutação não corresponde ao usuário ou grupo.

Quando AWS AppSync invalida uma conexão, o cliente recebe uma mensagem confirmando que sua assinatura foi cancelada:

```
{
  "message": "Subscription complete."
}
```

## Usar variáveis de contexto em filtros de invalidação de assinatura
<a name="aws-appsync-real-time-invalidation-context"></a>

Assim como nos filtros de assinatura aprimorados, você pode usar a [variável `context`](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html) na extensão do filtro de invalidação de assinatura para acessar determinados dados.

Por exemplo, é possível configurar um endereço de e-mail como a carga de invalidação na mutação e, em seguida, compará-lo ao atributo de e-mail ou à solicitação de um usuário inscrito autorizado com grupos de usuários do Amazon Cognito ou OpenID Connect. O filtro de invalidação definido no invalidador de assinatura `extensions.setSubscriptionInvalidationFilter()` verifica se o endereço de e-mail definido pela carga `extensions.invalidateSubscriptions()` da mutação corresponde ao endereço de e-mail recuperado do token JWT do usuário em `context.identity.claims.email`, iniciando a invalidação. 

# Construindo um WebSocket cliente em tempo real em AWS AppSync
<a name="real-time-websocket-client"></a>

**Importante**  
A partir de 13 de março de 2025, você pode criar uma PubSub API em tempo real baseada no WebSockets uso de AWS AppSync Eventos. Para obter mais informações, consulte [Publicar eventos WebSocket](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) no *Guia do desenvolvedor de AWS AppSync eventos*.

AWS AppSyncO WebSocket cliente em tempo real da GraphQL permite assinaturas do GraphQL por meio de um processo de várias etapas. O cliente primeiro estabelece uma WebSocket conexão com o endpoint AWS AppSync em tempo real, envia uma mensagem de inicialização da conexão e aguarda a confirmação. Após a conexão bem-sucedida, o cliente registra as assinaturas enviando mensagens iniciais com consultas exclusivas e do IDs GraphQL. AWS AppSync confirma assinaturas bem-sucedidas com mensagens de confirmação. O cliente recebe os eventos de assinatura, que são enviados pelas mutações correspondentes. Para manter a conexão, AWS AppSync envia mensagens periódicas de manutenção de atividade. Ao terminar, o cliente cancela o registro das assinaturas enviando mensagens de interrupção. Esse sistema suporta várias assinaturas em uma única WebSocket conexão e acomoda vários modos de autorização, incluindo chaves de API, grupos de usuários do Amazon Cognito, IAM e Lambda.

## Implementação de WebSocket cliente em tempo real para assinaturas do GraphQL
<a name="appsynclong-real-time-websocket-client-implementation-guide-for-graphql-subscriptions"></a>

O diagrama de sequência e as etapas a seguir mostram o fluxo de trabalho de assinaturas em tempo real entre o WebSocket cliente, o cliente HTTP e. AWS AppSync

![\[Sequence diagram showing WebSocket client, AppSync endpoints, and HTTP client interactions for real-time subscriptions.\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/realtime-client-flow.png)


1. O cliente estabelece uma WebSocket conexão com o endpoint AWS AppSync em tempo real. Se houver um erro de rede, o cliente deverá fazer um recuo exponencial com variação. Para obter mais informações, consulte [Recuo exponencial e instabilidade no blog de arquitetura](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/). AWS 

1. (Opcional) Depois de estabelecer a WebSocket conexão com sucesso, o cliente envia uma `connection_init` mensagem.

1. Se `connection_init` for enviado, o cliente espera por uma `connection_ack` mensagem de AWS AppSync. Essa mensagem inclui um parâmetro `connectionTimeoutMs`, que é o tempo de espera máximo em milissegundos para uma mensagem `"ka"`, keep-alive.

1. AWS AppSync envia `"ka"` mensagens periodicamente. O cliente monitora o horário de recebimento de cada mensagem `"ka"`. Se o cliente não receber uma mensagem `"ka"` em `connectionTimeoutMs` milissegundos, ele deverá fechar a conexão.

1. O cliente registra a assinatura enviando uma mensagem de assinatura `start`. Uma única WebSocket conexão suporta várias assinaturas, mesmo que elas estejam em modos de autorização diferentes.

1. O cliente espera o envio de `start_ack` mensagens AWS AppSync para confirmar as assinaturas bem-sucedidas. Se houver um erro, AWS AppSync retornará uma `"type": "error"` mensagem.

1. O cliente recebe os eventos de assinatura, que são enviados após a chamada de uma mutação correspondente. As consultas e mutações geralmente são enviadas `https://` para o endpoint do GraphQL AWS AppSync . As assinaturas fluem pelo endpoint AWS AppSync em tempo real usando o secure WebSocket (). `wss://`

1. O cliente cancela o registro da assinatura enviando uma mensagem de assinatura `stop`.

1. Depois de cancelar o registro de todas as assinaturas e verificar se não há mensagens sendo transferidas pelo WebSocket, o cliente pode se desconectar da conexão. WebSocket 

## Detalhes do aperto de mão para estabelecer a conexão WebSocket
<a name="handshake-details-to-establish-the-websocket-connection"></a>

Para se conectar e iniciar um handshake bem-sucedido com AWS AppSync, um WebSocket cliente precisa do seguinte:
+ O endpoint AWS AppSync em tempo real
+ Cabeçalhos — contêm informações relevantes para o AWS AppSync endpoint e a autorização. AWS AppSync suporta os três métodos a seguir para fornecer cabeçalhos: 
  + Cabeçalhos por meio da string de consulta
    + As informações do cabeçalho são codificadas como uma string base64, derivada de um objeto JSON em string. Esse objeto JSON contém detalhes relevantes para o AWS AppSync endpoint e a autorização. O conteúdo do objeto JSON varia de acordo com o modo de autorização.
  + Cabeçalhos por meio de `Sec-WebSocket-Protocol`
    + Uma string codificada em Base64URL do objeto JSON stringificado que contém informações relevantes para o AWS AppSync endpoint e a autorização é passada como protocolo no cabeçalho. `Sec-WebSocket-Protocol` O conteúdo do objeto JSON varia de acordo com o modo de autorização.
  + Cabeçalhos por meio de cabeçalhos HTTP padrão:
    + Os cabeçalhos podem ser passados como cabeçalhos HTTP padrão na solicitação de conexão, da mesma forma que os cabeçalhos são passados para consultas e mutações do GraphQL. AWS AppSync No entanto, a passagem de cabeçalhos por meio de cabeçalhos HTTP padrão não é compatível com solicitações de conexão API privadas.
+  `payload`: string codificada em Base64 de `payload`. A carga útil só será necessária se os cabeçalhos forem fornecidos usando a string de consulta

Com esses requisitos, um WebSocket cliente pode se conectar à URL, que contém o endpoint em tempo real com a string de consulta, usando `graphql-ws` como WebSocket protocolo.

### Descobrir o endpoint em tempo real com base no endpoint do GraphQL
<a name="discovering-the-appsync-real-time-endpoint-from-the-appsync-graphql-endpoint"></a>

O endpoint do AWS AppSync GraphQL e o endpoint AWS AppSync em tempo real são ligeiramente diferentes em protocolo e domínio. Você pode recuperar o endpoint do GraphQL usando AWS Command Line Interface o AWS CLI comando (). `aws appsync get-graphql-api`

****AWS AppSync Ponto final do GraphQL:****  
 `https://example1234567890000.appsync-api.us-east-1.amazonaws.com/graphql`

****AWS AppSync endpoint em tempo real:****  
 `wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql`

Os aplicativos podem se conectar ao endpoint do AWS AppSync GraphQL (`https://`) usando qualquer cliente HTTP para consultas e mutações. Os aplicativos podem se conectar ao endpoint AWS AppSync em tempo real (`wss://`) usando qualquer WebSocket cliente para assinaturas.

Os nomes de domínio personalizados permitem interagir com os dois endpoints usando um único domínio. Por exemplo, se você configurar `api.example.com` como seu domínio personalizado, poderá interagir com seus endpoints do GraphQL e em tempo real usando estes: URLs

**AWS AppSync endpoint GraphQL de domínio personalizado:**  
`https://api.example.com/graphql`

**AWS AppSync endpoint em tempo real de domínio personalizado:**  
`wss://api.example.com/graphql/realtime`

## Formato do parâmetro de cabeçalho com base no modo de autorização AWS AppSync da API
<a name="header-parameter-format-based-on-appsync-api-authorization-mode"></a>

O formato do `header` objeto usado na string de consulta de conexão varia de acordo com o modo de autorização da AWS AppSync API. O `host` campo no objeto se refere ao endpoint do AWS AppSync GraphQL, que é usado para validar a conexão mesmo se a `wss://` chamada for feita no endpoint em tempo real. Para iniciar o handshake e estabelecer a conexão autorizada, `payload` deve ser um objeto JSON vazio. A carga útil só será necessária se os cabeçalhos forem passados por meio da string de consulta.

As seções a seguir demonstram os formatos de cabeçalho para cada modo de autorização.

### Chave de API
<a name="api-key"></a>

#### Cabeçalho da chave da API
<a name="api-key-list"></a>

**Conteúdo do cabeçalho**
+  `"host": <string>`: o host do endpoint do AWS AppSync GraphQL ou do seu nome de domínio personalizado.
+  `"x-api-key": <string>`: a chave de API configurada para a AWS AppSync API.

**Exemplo**

```
{
    "host":"example1234567890000.appsync-api.us-east-1.amazonaws.com",
    "x-api-key":"da2-12345678901234567890123456"
}
```

**Cabeçalhos por meio da string de consulta**

Primeiro, um objeto JSON contendo o `host` e o `x-api-key` é convertido em uma string. Em seguida, essa string é codificada usando a codificação base64. A string codificada em base64 resultante é adicionada como um parâmetro de consulta nomeado `header` ao WebSocket URL para estabelecer a conexão com o AWS AppSync endpoint em tempo real. A URL da solicitação resultante assume a seguinte forma:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql?header=eyJob3N0IjoiZXhhbXBsZTEyMzQ1Njc4OTAwMDAuYXBwc3luYy1hcGkudXMtZWFzdC0xLmFtYXpvbmF3cy5jb20iLCJ4LWFtei1kYXRlIjoiMjAyMDA0MDFUMDAxMDEwWiIsIngtYXBpLWtleSI6ImRhMi16NHc0NHZoczV6Z2MzZHRqNXNranJsbGxqaSJ9&payload=e30=
```

É importante observar que, além do objeto de cabeçalho codificado em base64, um objeto JSON vazio \$1\$1 também é codificado em base64 e incluído como um parâmetro de consulta separado nomeado na URL. `payload` WebSocket

**Cabeçalhos por meio de `Sec-WebSocket-Protocol`**

Um objeto JSON contendo o `host` e o `x-api-key` é convertido em uma string e, em seguida, codificado usando a codificação base64Url. A string codificada em base64Url resultante é prefixada com `header-`. Essa string prefixada é então usada como um novo subprotocolo, além do `Sec-WebSocket-Protocol` cabeçalho, ao `graphql-ws` estabelecer a WebSocket conexão com o endpoint AWS AppSync em tempo real. 

A URL da solicitação resultante assume a seguinte forma:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

O cabeçalho `Sec-WebSocket-Protocol` contém o seguinte valor:

```
"sec-websocket-protocol" : ["graphql-ws", "header-ewogICAgImhvc3QiOiJleGFtcGxlMTIzNDU2Nzg5MDAwMC5hcHBzeW5jLWFwaS51cy1lYXN0LTEuYW1hem9uYXdzLmNvbSIsCiAgICAieC1hcGkta2V5IjoiZGEyLTEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Igp9"]
```

**Cabeçalhos por meio de cabeçalhos HTTP padrão**

Nesse método, as informações da chave do host e da API são transmitidas usando cabeçalhos HTTP padrão ao estabelecer a WebSocket conexão com o endpoint AWS AppSync em tempo real. A URL da solicitação resultante assume a seguinte forma:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

Os cabeçalhos de solicitação incluiriam o seguinte:

```
"sec-websocket-protocol" : ["graphql-ws"]
"host":"example1234567890000.appsync-api.us-east-1.amazonaws.com",
"x-api-key":"da2-12345678901234567890123456"
```

### Grupos de usuários do Amazon Cognito e OpenID Connect (OIDC)
<a name="amazon-cognito-user-pools-and-openid-connect-oidc"></a>

#### Amazon Cognito e cabeçalho OIDC
<a name="amazon-cognito-user-pools-and-openid-connect-oidc-list"></a>

Conteúdo do cabeçalho:
+  `"Authorization": <string>`: Um token de ID JWT. O cabeçalho pode usar um [esquema Bearer](https://datatracker.ietf.org/doc/html/rfc6750#section-2.1).
+  `"host": <string>`: o host do endpoint do AWS AppSync GraphQL ou do seu nome de domínio personalizado.

Exemplo:

```
{
    "Authorization":"eyEXAMPLEiJjbG5xb3A5eW5MK09QYXIrMTJHWEFLSXBieU5WNHhsQjEXAMPLEnM2WldvPSIsImFsZyI6IlEXAMPLEn0.eyEXAMPLEiJhNmNmMjcwNy0xNjgxLTQ1NDItOWYxOC1lNjY0MTg2NjlkMzYiLCJldmVudF9pZCI6ImVkMzM5MmNkLWNjYTMtNGM2OC1hNDYyLTJlZGI3ZTNmY2FjZiIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoiYXdzLmNvZ25pdG8uc2lnbmluLnVzZXIuYWRtaW4iLCJhdXRoX3RpbWUiOjE1Njk0NTc3MTgsImlzcyI6Imh0dHBzOlwvXC9jb2duaXRvLWlkcC5hcC1zb3V0aGVhc3QtMi5hbWF6b25hd3MuY29tXC9hcC1zb3V0aGVhc3QtMl83OHY0SVZibVAiLCJleHAiOjE1Njk0NjEzMjAsImlhdCI6MTU2OTQ1NzcyMCwianRpIjoiNTgzZjhmYmMtMzk2MS00YzA4LWJhZTAtYzQyY2IxMTM5NDY5IiwiY2xpZW50X2lkIjoiM3FlajVlMXZmMzd1N3RoZWw0dG91dDJkMWwiLCJ1c2VybmFtZSI6ImVsb3EXAMPLEn0.B4EXAMPLEFNpJ6ikVp7e6DRee95V6Qi-zEE2DJH7sHOl2zxYi7f-SmEGoh2AD8emxQRYajByz-rE4Jh0QOymN2Ys-ZIkMpVBTPgu-TMWDyOHhDUmUj2OP82yeZ3wlZAtr_gM4LzjXUXmI_K2yGjuXfXTaa1mvQEBG0mQfVd7SfwXB-jcv4RYVi6j25qgow9Ew52ufurPqaK-3WAKG32KpV8J4-Wejq8t0c-yA7sb8EnB551b7TU93uKRiVVK3E55Nk5ADPoam_WYE45i3s5qVAP_-InW75NUoOCGTsS8YWMfb6ecHYJ-1j-bzA27zaT9VjctXn9byNFZmEXAMPLExw",
    "host":"example1234567890000.appsync-api.us-east-1.amazonaws.com"
}
```

**Cabeçalhos por meio da string de consulta**

Primeiro, um objeto JSON contendo o `host` e o `Authorization` é convertido em uma string. Em seguida, essa string é codificada usando a codificação base64. A string codificada em base64 resultante é adicionada como um parâmetro de consulta nomeado `header` ao WebSocket URL para estabelecer a conexão com o AWS AppSync endpoint em tempo real. A URL da solicitação resultante assume a seguinte forma:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql?header=eyJBdXRob3JpemF0aW9uIjoiZXlKcmFXUWlPaUpqYkc1eGIzQTVlVzVNSzA5UVlYSXJNVEpIV0VGTFNYQmllVTVXTkhoc1FqaFBWVzlZTW5NMldsZHZQU0lzSW1Gc1p5STZJbEpUTWpVMkluMC5leUp6ZFdJaU9pSmhObU5tTWpjd055MHhOamd4TFRRMU5ESXRPV1l4T0MxbE5qWTBNVGcyTmpsa016WWlMQ0psZG1WdWRGOXBaQ0k2SW1Wa016TTVNbU5rTFdOallUTXROR00yT0MxaE5EWXlMVEpsWkdJM1pUTm1ZMkZqWmlJc0luUnZhMlZ1WDNWelpTSTZJbUZqWTJWemN5SXNJbk5qYjNCbElqb2lZWGR6TG1OdloyNXBkRzh1YzJsbmJtbHVMblZ6WlhJdVlXUnRhVzRpTENKaGRYUm9YM1JwYldVaU9qRTFOamswTlRjM01UZ3NJbWx6Y3lJNkltaDBkSEJ6T2x3dlhDOWpiMmR1YVhSdkxXbGtjQzVoY0MxemIzVjBhR1ZoYzNRdE1pNWhiV0Y2YjI1aGQzTXVZMjl0WEM5aGNDMXpiM1YwYUdWaGMzUXRNbDgzT0hZMFNWWmliVkFpTENKbGVIQWlPakUxTmprME5qRXpNakFzSW1saGRDSTZNVFUyT1RRMU56Y3lNQ3dpYW5ScElqb2lOVGd6WmpobVltTXRNemsyTVMwMFl6QTRMV0poWlRBdFl6UXlZMkl4TVRNNU5EWTVJaXdpWTJ4cFpXNTBYMmxrSWpvaU0zRmxhalZsTVhabU16ZDFOM1JvWld3MGRHOTFkREprTVd3aUxDSjFjMlZ5Ym1GdFpTSTZJbVZzYjNKNllXWmxJbjAuQjRjZEp0aDNLRk5wSjZpa1ZwN2U2RFJlZTk1VjZRaS16RUUyREpIN3NIT2wyenhZaTdmLVNtRUdvaDJBRDhlbXhRUllhakJ5ei1yRTRKaDBRT3ltTjJZcy1aSWtNcFZCVFBndS1UTVdEeU9IaERVbVVqMk9QODJ5ZVozd2xaQXRyX2dNNEx6alhVWG1JX0syeUdqdVhmWFRhYTFtdlFFQkcwbVFmVmQ3U2Z3WEItamN2NFJZVmk2ajI1cWdvdzlFdzUydWZ1clBxYUstM1dBS0czMktwVjhKNC1XZWpxOHQwYy15QTdzYjhFbkI1NTFiN1RVOTN1S1JpVlZLM0U1NU5rNUFEUG9hbV9XWUU0NWkzczVxVkFQXy1Jblc3NU5Vb09DR1RzUzhZV01mYjZlY0hZSi0xai1iekEyN3phVDlWamN0WG45YnlORlptS0xwQTJMY3h3IiwiaG9zdCI6ImV4YW1wbGUxMjM0NTY3ODkwMDAwLmFwcHN5bmMtYXBpLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tIn0=&payload=e30=
```

É importante observar que, além do objeto de cabeçalho codificado em base64, um objeto JSON vazio \$1\$1 também é codificado em base64 e incluído como um parâmetro de consulta separado nomeado na URL. `payload` WebSocket

**Cabeçalhos por meio de `Sec-WebSocket-Protocol`**

Um objeto JSON contendo o `host` e o `Authorization` é convertido em uma string e, em seguida, codificado usando a codificação base64Url. A string codificada em base64Url resultante é prefixada com `header-`. Essa string prefixada é então usada como um novo subprotocolo, além do `Sec-WebSocket-Protocol` cabeçalho, ao `graphql-ws` estabelecer a WebSocket conexão com o endpoint AWS AppSync em tempo real. 

A URL da solicitação resultante assume a seguinte forma:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

O cabeçalho `Sec-WebSocket-Protocol` contém o seguinte valor:

```
"sec-websocket-protocol" : ["graphql-ws", "header-ewogICAgImhvc3QiOiJleGFtcGxlMTIzNDU2Nzg5MDAwMC5hcHBzeW5jLWFwaS51cy1lYXN0LTEuYW1hem9uYXdzLmNvbSIsCiAgICAieC1hcGkta2V5IjoiZGEyLTEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Igp9"]
```

**Cabeçalhos por meio de cabeçalhos HTTP padrão**

Nesse método, as informações do host e da autorização são transmitidas usando cabeçalhos HTTP padrão ao estabelecer a WebSocket conexão com o endpoint AWS AppSync em tempo real. A URL da solicitação resultante assume a seguinte forma:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

Os cabeçalhos de solicitação incluiriam o seguinte:

```
"sec-websocket-protocol" : ["graphql-ws"]
"Authorization":"eyEXAMPLEiJjbG5xb3A5eW5MK09QYXIrMTJHWEFLSXBieU5WNHhsQjEXAMPLEnM2WldvPSIsImFsZyI6IlEXAMPLEn0.eyEXAMPLEiJhNmNmMjcwNy0xNjgxLTQ1NDItOWYxOC1lNjY0MTg2NjlkMzYiLCJldmVudF9pZCI6ImVkMzM5MmNkLWNjYTMtNGM2OC1hNDYyLTJlZGI3ZTNmY2FjZiIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoiYXdzLmNvZ25pdG8uc2lnbmluLnVzZXIuYWRtaW4iLCJhdXRoX3RpbWUiOjE1Njk0NTc3MTgsImlzcyI6Imh0dHBzOlwvXC9jb2duaXRvLWlkcC5hcC1zb3V0aGVhc3QtMi5hbWF6b25hd3MuY29tXC9hcC1zb3V0aGVhc3QtMl83OHY0SVZibVAiLCJleHAiOjE1Njk0NjEzMjAsImlhdCI6MTU2OTQ1NzcyMCwianRpIjoiNTgzZjhmYmMtMzk2MS00YzA4LWJhZTAtYzQyY2IxMTM5NDY5IiwiY2xpZW50X2lkIjoiM3FlajVlMXZmMzd1N3RoZWw0dG91dDJkMWwiLCJ1c2VybmFtZSI6ImVsb3EXAMPLEn0.B4EXAMPLEFNpJ6ikVp7e6DRee95V6Qi-zEE2DJH7sHOl2zxYi7f-SmEGoh2AD8emxQRYajByz-rE4Jh0QOymN2Ys-ZIkMpVBTPgu-TMWDyOHhDUmUj2OP82yeZ3wlZAtr_gM4LzjXUXmI_K2yGjuXfXTaa1mvQEBG0mQfVd7SfwXB-jcv4RYVi6j25qgow9Ew52ufurPqaK-3WAKG32KpV8J4-Wejq8t0c-yA7sb8EnB551b7TU93uKRiVVK3E55Nk5ADPoam_WYE45i3s5qVAP_-InW75NUoOCGTsS8YWMfb6ecHYJ-1j-bzA27zaT9VjctXn9byNFZmEXAMPLExw",
"host":"example1234567890000.appsync-api.us-east-1.amazonaws.com"
```

### IAM
<a name="iam"></a>

#### Cabeçalho IAM
<a name="iam-list"></a>

**Conteúdo do cabeçalho**
+  `"accept": "application/json, text/javascript"`: Um parâmetro `<string>` constante.
+  `"content-encoding": "amz-1.0"`: Um parâmetro `<string>` constante.
+  `"content-type": "application/json; charset=UTF-8"`: Um parâmetro `<string>` constante.
+  `"host": <string>`: Esse é o host do endpoint do AWS AppSync GraphQL.
  + `"x-amz-date": <string>`: O carimbo de data/hora deve ser em UTC e no seguinte formato: ISO 8601 YYYYMMDD'T'HHMMSS'Z '. Por exemplo, 20150830T123600Z é um carimbo de data/hora válido. Não inclua milissegundos no carimbo de data/hora. Para obter mais informações, consulte [Como lidar com datas no Signature versão 4](https://docs.aws.amazon.com/general/latest/gr/sigv4-date-handling.html) na *Referência geral da AWS*.
  +  `"X-Amz-Security-Token": <string>`: o token da AWS sessão, que é necessário ao usar credenciais de segurança temporárias. Para obter mais informações, consulte [Usar credenciais temporárias com recursos da  AWS](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_credentials_temp_use-resources.html) no *Guia do usuário do IAM*.
  +  `"Authorization": <string>`: Informações de assinatura do Signature Version 4 (SigV4) para o AWS AppSync endpoint. Para obter mais informações sobre o processo de assinatura, consulte [Tarefa 4: Adicionar a assinatura à solicitação HTTP](https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html) na *Referência geral da AWS*.

A solicitação HTTP de assinatura do SigV4 inclui um URL canônico, que é o endpoint do GraphQL do AWS AppSync com `/connect` anexado. A AWS região do endpoint do serviço é a mesma região em que você está usando a AWS AppSync API, e o nome do serviço é 'appsync'. A solicitação HTTP para assinar é a seguinte:

```
{
  url: "https://example1234567890000.appsync-api.us-east-1.amazonaws.com/graphql/connect",
  data: "{}",
  method: "POST",
  headers: {
    "accept": "application/json, text/javascript",
    "content-encoding": "amz-1.0",
    "content-type": "application/json; charset=UTF-8",
  }
}
```

**Exemplo**

```
{
  "accept": "application/json, text/javascript",
  "content-encoding": "amz-1.0",
  "content-type": "application/json; charset=UTF-8",
  "host": "example1234567890000.appsync-api.us-east-1.amazonaws.com",
  "x-amz-date": "20200401T001010Z",
  "X-Amz-Security-Token": "AgEXAMPLEZ2luX2VjEAoaDmFwLXNvdXRoZWFEXAMPLEcwRQIgAh97Cljq7wOPL8KsxP3YtDuyc/9hAj8PhJ7Fvf38SgoCIQDhJEXAMPLEPspioOztj++pEagWCveZUjKEn0zyUhBEXAMPLEjj//////////8BEXAMPLExODk2NDgyNzg1NSIMo1mWnpESWUoYw4BkKqEFSrm3DXuL8w+ZbVc4JKjDP4vUCKNR6Le9C9pZp9PsW0NoFy3vLBUdAXEXAMPLEOVG8feXfiEEA+1khgFK/wEtwR+9zF7NaMMMse07wN2gG2tH0eKMEXAMPLEQX+sMbytQo8iepP9PZOzlZsSFb/dP5Q8hk6YEXAMPLEYcKZsTkDAq2uKFQ8mYUVA9EtQnNRiFLEY83aKvG/tqLWNnGlSNVx7SMcfovkFDqQamm+88y1OwwAEYK7qcoceX6Z7GGcaYuIfGpaX2MCCELeQvZ+8WxEgOnIfz7GYvsYNjLZSaRnV4G+ILY1F0QNW64S9Nvj+BwDg3ht2CrNvpwjVYlj9U3nmxE0UG5ne83LL5hhqMpm25kmL7enVgw2kQzmU2id4IKu0C/WaoDRuO2F5zE63vJbxN8AYs7338+4B4HBb6BZ6OUgg96Q15RA41/gIqxaVPxyTpDfTU5GfSLxocdYeniqqpFMtZG2n9d0u7GsQNcFkNcG3qDZm4tDo8tZbuym0a2VcF2E5hFEgXBa+XLJCfXi/77OqAEjP0x7Qdk3B43p8KG/BaioP5RsV8zBGvH1zAgyPha2rN70/tT13yrmPd5QYEfwzexjKrV4mWIuRg8NTHYSZJUaeyCwTom80VFUJXG+GYTUyv5W22aBcnoRGiCiKEYTLOkgXecdKFTHmcIAejQ9Welr0a196Kq87w5KNMCkcCGFnwBNFLmfnbpNqT6rUBxxs3X5ntX9d8HVtSYINTsGXXMZCJ7fnbWajhg/aox0FtHX21eF6qIGT8j1z+l2opU+ggwUgkhUUgCH2TfqBj+MLMVVvpgqJsPKt582caFKArIFIvO+9QupxLnEH2hz04TMTfnU6bQC6z1buVe7h+tOLnh1YPFsLQ88anib/7TTC8k9DsBTq0ASe8R2GbSEsmO9qbbMwgEaYUhOKtGeyQsSJdhSk6XxXThrWL9EnwBCXDkICMqdntAxyyM9nWsZ4bL9JHqExgWUmfWChzPFAqn3F4y896UqHTZxlq3WGypn5HHcem2Hqf3IVxKH1inhqdVtkryEiTWrI7ZdjbqnqRbl+WgtPtKOOweDlCaRs3R2qXcbNgVhleMk4IWnF8D1695AenU1LwHjOJLkCjxgNFiWAFEPH9aEXAMPLExA==",
  "Authorization": "AWS4-HMAC-SHA256 Credential=XXXXXXXXXXXXXXXXXXX/20200401/us-east-1/appsync/aws4_request, SignedHeaders=accept;content-encoding;content-type;host;x-amz-date;x-amz-security-token, Signature=83EXAMPLEbcc1fe3ee69f75cd5ebbf4cb4f150e4f99cec869f149c5EXAMPLEdc"
}
```

**Cabeçalhos por meio da string de consulta**

Primeiro, um objeto JSON contendo o `host` (endpoint do AWS AppSync GraphQL) e os outros cabeçalhos de autorização é convertido em uma string. Em seguida, essa string é codificada usando a codificação base64. A string codificada em base64 resultante é adicionada ao WebSocket URL como um parâmetro de consulta chamado. `header` A URL da solicitação resultante assume a seguinte forma:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql?header=eyJBdXRob3JpemF0aW9uIjoiZXlKcmFXUWlPaUpqYkc1eGIzQTVlVzVNSzA5UVlYSXJNVEpIV0VGTFNYQmllVTVXTkhoc1FqaFBWVzlZTW5NMldsZHZQU0lzSW1Gc1p5STZJbEpUTWpVMkluMC5leUp6ZFdJaU9pSmhObU5tTWpjd055MHhOamd4TFRRMU5ESXRPV1l4T0MxbE5qWTBNVGcyTmpsa016WWlMQ0psZG1WdWRGOXBaQ0k2SW1Wa016TTVNbU5rTFdOallUTXROR00yT0MxaE5EWXlMVEpsWkdJM1pUTm1ZMkZqWmlJc0luUnZhMlZ1WDNWelpTSTZJbUZqWTJWemN5SXNJbk5qYjNCbElqb2lZWGR6TG1OdloyNXBkRzh1YzJsbmJtbHVMblZ6WlhJdVlXUnRhVzRpTENKaGRYUm9YM1JwYldVaU9qRTFOamswTlRjM01UZ3NJbWx6Y3lJNkltaDBkSEJ6T2x3dlhDOWpiMmR1YVhSdkxXbGtjQzVoY0MxemIzVjBhR1ZoYzNRdE1pNWhiV0Y2YjI1aGQzTXVZMjl0WEM5aGNDMXpiM1YwYUdWaGMzUXRNbDgzT0hZMFNWWmliVkFpTENKbGVIQWlPakUxTmprME5qRXpNakFzSW1saGRDSTZNVFUyT1RRMU56Y3lNQ3dpYW5ScElqb2lOVGd6WmpobVltTXRNemsyTVMwMFl6QTRMV0poWlRBdFl6UXlZMkl4TVRNNU5EWTVJaXdpWTJ4cFpXNTBYMmxrSWpvaU0zRmxhalZsTVhabU16ZDFOM1JvWld3MGRHOTFkREprTVd3aUxDSjFjMlZ5Ym1GdFpTSTZJbVZzYjNKNllXWmxJbjAuQjRjZEp0aDNLRk5wSjZpa1ZwN2U2RFJlZTk1VjZRaS16RUUyREpIN3NIT2wyenhZaTdmLVNtRUdvaDJBRDhlbXhRUllhakJ5ei1yRTRKaDBRT3ltTjJZcy1aSWtNcFZCVFBndS1UTVdEeU9IaERVbVVqMk9QODJ5ZVozd2xaQXRyX2dNNEx6alhVWG1JX0syeUdqdVhmWFRhYTFtdlFFQkcwbVFmVmQ3U2Z3WEItamN2NFJZVmk2ajI1cWdvdzlFdzUydWZ1clBxYUstM1dBS0czMktwVjhKNC1XZWpxOHQwYy15QTdzYjhFbkI1NTFiN1RVOTN1S1JpVlZLM0U1NU5rNUFEUG9hbV9XWUU0NWkzczVxVkFQXy1Jblc3NU5Vb09DR1RzUzhZV01mYjZlY0hZSi0xai1iekEyN3phVDlWamN0WG45YnlORlptS0xwQTJMY3h3IiwiaG9zdCI6ImV4YW1wbGUxMjM0NTY3ODkwMDAwLmFwcHN5bmMtYXBpLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tIn0=&payload=e30=
```

É importante observar que, além do objeto de cabeçalho codificado em base64, um objeto JSON vazio \$1\$1 também é codificado em base64 e incluído como um parâmetro de consulta separado nomeado na URL. `payload` WebSocket

**Cabeçalhos por meio de `Sec-WebSocket-Protocol`**

Um objeto JSON contendo o `host` e os outros cabeçalhos de autorização é convertido em uma string e, em seguida, codificado usando a codificação base64Url. A string codificada em base64Url resultante é prefixada com `header-`. Essa string prefixada é então usada como um novo subprotocolo, além do `Sec-WebSocket-Protocol` cabeçalho, ao `graphql-ws` estabelecer a WebSocket conexão com o endpoint AWS AppSync em tempo real. 

A URL da solicitação resultante assume a seguinte forma:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

O cabeçalho `Sec-WebSocket-Protocol` contém o seguinte valor:

```
"sec-websocket-protocol" : ["graphql-ws", "header-ew0KICAiYWNjZXB0IjogImFwcGxpY2F0aW9uL2pzb24sIHRleHQvamF2YXNjcmlwdCIsDQogICJjb250ZW50LWVuY29kaW5nIjogImFtei0xLjAiLA0KICAiY29udGVudC10eXBlIjogImFwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9VVRGLTgiLA0KICAiaG9zdCI6ICJleGFtcGxlMTIzNDU2Nzg5MDAwMC5hcHBzeW5jLWFwaS51cy1lYXN0LTEuYW1hem9uYXdzLmNvbSIsDQogICJ4LWFtei1kYXRlIjogIjIwMjAwNDAxVDAwMTAxMFoiLA0KICAiWC1BbXotU2VjdXJpdHktVG9rZW4iOiAiQWdFWEFNUExFWjJsdVgyVmpFQW9hRG1Gd0xYTnZkWFJvWldGRVhBTVBMRWN3UlFJZ0FoOTdDbGpxN3dPUEw4S3N4UDNZdER1eWMvOWhBajhQaEo3RnZmMzhTZ29DSVFEaEpFWEFNUExFUHNwaW9PenRqKytwRWFnV0N2ZVpVaktFbjB6eVVoQkVYQU1QTEVqai8vLy8vLy8vLy84QkVYQU1QTEV4T0RrMk5EZ3lOemcxTlNJTW8xbVducEVTV1VvWXc0QmtLcUVGU3JtM0RYdUw4dytaYlZjNEpLakRQNHZVQ0tOUjZMZTlDOXBacDlQc1cwTm9GeTN2TEJVZEFYRVhBTVBMRU9WRzhmZVhmaUVFQSsxa2hnRksvd0V0d1IrOXpGN05hTU1Nc2UwN3dOMmdHMnRIMGVLTUVYQU1QTEVRWCtzTWJ5dFFvOGllcFA5UFpPemxac1NGYi9kUDVROGhrNllFWEFNUExFWWNLWnNUa0RBcTJ1S0ZROG1ZVVZBOUV0UW5OUmlGTEVZODNhS3ZHL3RxTFdObkdsU05WeDdTTWNmb3ZrRkRxUWFtbSs4OHkxT3d3QUVZSzdxY29jZVg2WjdHR2NhWXVJZkdwYVgyTUNDRUxlUXZaKzhXeEVnT25JZno3R1l2c1lOakxaU2FSblY0RytJTFkxRjBRTlc2NFM5TnZqK0J3RGczaHQyQ3JOdnB3alZZbGo5VTNubXhFMFVHNW5lODNMTDVoaHFNcG0yNWttTDdlblZndzJrUXptVTJpZDRJS3UwQy9XYW9EUnVPMkY1ekU2M3ZKYnhOOEFZczczMzgrNEI0SEJiNkJaNk9VZ2c5NlExNVJBNDEvZ0lxeGFWUHh5VHBEZlRVNUdmU0x4b2NkWWVuaXFxcEZNdFpHMm45ZDB1N0dzUU5jRmtOY0czcURabTR0RG84dFpidXltMGEyVmNGMkU1aEZFZ1hCYStYTEpDZlhpLzc3T3FBRWpQMHg3UWRrM0I0M3A4S0cvQmFpb1A1UnNWOHpCR3ZIMXpBZ3lQaGEyck43MC90VDEzeXJtUGQ1UVlFZnd6ZXhqS3JWNG1XSXVSZzhOVEhZU1pKVWFleUN3VG9tODBWRlVKWEcrR1lUVXl2NVcyMmFCY25vUkdpQ2lLRVlUTE9rZ1hlY2RLRlRIbWNJQWVqUTlXZWxyMGExOTZLcTg3dzVLTk1Da2NDR0Zud0JORkxtZm5icE5xVDZyVUJ4eHMzWDVudFg5ZDhIVnRTWUlOVHNHWFhNWkNKN2ZuYldhamhnL2FveDBGdEhYMjFlRjZxSUdUOGoxeitsMm9wVStnZ3dVZ2toVVVnQ0gyVGZxQmorTUxNVlZ2cGdxSnNQS3Q1ODJjYUZLQXJJRkl2Tys5UXVweExuRUgyaHowNFRNVGZuVTZiUUM2ejFidVZlN2grdE9MbmgxWVBGc0xRODhhbmliLzdUVEM4azlEc0JUcTBBU2U4UjJHYlNFc21POXFiYk13Z0VhWVVoT0t0R2V5UXNTSmRoU2s2WHhYVGhyV0w5RW53QkNYRGtJQ01xZG50QXh5eU05bldzWjRiTDlKSHFFeGdXVW1mV0NoelBGQXFuM0Y0eTg5NlVxSFRaeGxxM1dHeXBuNUhIY2VtMkhxZjNJVnhLSDFpbmhxZFZ0a3J5RWlUV3JJN1pkamJxbnFSYmwrV2d0UHRLT093ZURsQ2FSczNSMnFYY2JOZ1ZobGVNazRJV25GOEQxNjk1QWVuVTFMd0hqT0pMa0NqeGdORmlXQUZFUEg5YUVYQU1QTEV4QT09IiwNCiAgIkF1dGhvcml6YXRpb24iOiAiQVdTNC1ITUFDLVNIQTI1NiBDcmVkZW50aWFsPVhYWFhYWFhYWFhYWFhYWFhYWFgvMjAyMDA0MDEvdXMtZWFzdC0xL2FwcHN5bmMvYXdzNF9yZXF1ZXN0LCBTaWduZWRIZWFkZXJzPWFjY2VwdDtjb250ZW50LWVuY29kaW5nO2NvbnRlbnQtdHlwZTtob3N0O3gtYW16LWRhdGU7eC1hbXotc2VjdXJpdHktdG9rZW4sIFNpZ25hdHVyZT04M0VYQU1QTEViY2MxZmUzZWU2OWY3NWNkNWViYmY0Y2I0ZjE1MGU0Zjk5Y2VjODY5ZjE0OWM1RVhBTVBMRWRjIg0KfQ"]
```

**Cabeçalhos por meio de cabeçalhos HTTP padrão**

Nesse método, o host e as outras informações de autorização são transmitidas usando cabeçalhos HTTP padrão ao estabelecer a WebSocket conexão com o endpoint AWS AppSync em tempo real. A URL da solicitação resultante assume a seguinte forma:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

Os cabeçalhos de solicitação incluiriam o seguinte:

```
"sec-websocket-protocol" : ["graphql-ws"]
"accept": "application/json, text/javascript",
"content-encoding": "amz-1.0",
"content-type": "application/json; charset=UTF-8",
"host": "example1234567890000.appsync-api.us-east-1.amazonaws.com",
"x-amz-date": "20200401T001010Z",
"X-Amz-Security-Token": "AgEXAMPLEZ2luX2VjEAoaDmFwLXNvdXRoZWFEXAMPLEcwRQIgAh97Cljq7wOPL8KsxP3YtDuyc/9hAj8PhJ7Fvf38SgoCIQDhJEXAMPLEPspioOztj++pEagWCveZUjKEn0zyUhBEXAMPLEjj//////////8BEXAMPLExODk2NDgyNzg1NSIMo1mWnpESWUoYw4BkKqEFSrm3DXuL8w+ZbVc4JKjDP4vUCKNR6Le9C9pZp9PsW0NoFy3vLBUdAXEXAMPLEOVG8feXfiEEA+1khgFK/wEtwR+9zF7NaMMMse07wN2gG2tH0eKMEXAMPLEQX+sMbytQo8iepP9PZOzlZsSFb/dP5Q8hk6YEXAMPLEYcKZsTkDAq2uKFQ8mYUVA9EtQnNRiFLEY83aKvG/tqLWNnGlSNVx7SMcfovkFDqQamm+88y1OwwAEYK7qcoceX6Z7GGcaYuIfGpaX2MCCELeQvZ+8WxEgOnIfz7GYvsYNjLZSaRnV4G+ILY1F0QNW64S9Nvj+BwDg3ht2CrNvpwjVYlj9U3nmxE0UG5ne83LL5hhqMpm25kmL7enVgw2kQzmU2id4IKu0C/WaoDRuO2F5zE63vJbxN8AYs7338+4B4HBb6BZ6OUgg96Q15RA41/gIqxaVPxyTpDfTU5GfSLxocdYeniqqpFMtZG2n9d0u7GsQNcFkNcG3qDZm4tDo8tZbuym0a2VcF2E5hFEgXBa+XLJCfXi/77OqAEjP0x7Qdk3B43p8KG/BaioP5RsV8zBGvH1zAgyPha2rN70/tT13yrmPd5QYEfwzexjKrV4mWIuRg8NTHYSZJUaeyCwTom80VFUJXG+GYTUyv5W22aBcnoRGiCiKEYTLOkgXecdKFTHmcIAejQ9Welr0a196Kq87w5KNMCkcCGFnwBNFLmfnbpNqT6rUBxxs3X5ntX9d8HVtSYINTsGXXMZCJ7fnbWajhg/aox0FtHX21eF6qIGT8j1z+l2opU+ggwUgkhUUgCH2TfqBj+MLMVVvpgqJsPKt582caFKArIFIvO+9QupxLnEH2hz04TMTfnU6bQC6z1buVe7h+tOLnh1YPFsLQ88anib/7TTC8k9DsBTq0ASe8R2GbSEsmO9qbbMwgEaYUhOKtGeyQsSJdhSk6XxXThrWL9EnwBCXDkICMqdntAxyyM9nWsZ4bL9JHqExgWUmfWChzPFAqn3F4y896UqHTZxlq3WGypn5HHcem2Hqf3IVxKH1inhqdVtkryEiTWrI7ZdjbqnqRbl+WgtPtKOOweDlCaRs3R2qXcbNgVhleMk4IWnF8D1695AenU1LwHjOJLkCjxgNFiWAFEPH9aEXAMPLExA==",
"Authorization": "AWS4-HMAC-SHA256 Credential=XXXXXXXXXXXXXXXXXXX/20200401/us-east-1/appsync/aws4_request, SignedHeaders=accept;content-encoding;content-type;host;x-amz-date;x-amz-security-token, Signature=83EXAMPLEbcc1fe3ee69f75cd5ebbf4cb4f150e4f99cec869f149c5EXAMPLEdc"
```

Para assinar a solicitação usando um domínio personalizado:

```
{
  url: "https://api.example.com/graphql/connect",
  data: "{}",
  method: "POST",
  headers: {
    "accept": "application/json, text/javascript",
    "content-encoding": "amz-1.0",
    "content-type": "application/json; charset=UTF-8",
  }
}
```

**Exemplo**

```
{
  "accept": "application/json, text/javascript",
  "content-encoding": "amz-1.0",
  "content-type": "application/json; charset=UTF-8",
  "host": "api.example.com",
  "x-amz-date": "20200401T001010Z",
  "X-Amz-Security-Token": "AgEXAMPLEZ2luX2VjEAoaDmFwLXNvdXRoZWFEXAMPLEcwRQIgAh97Cljq7wOPL8KsxP3YtDuyc/9hAj8PhJ7Fvf38SgoCIQDhJEXAMPLEPspioOztj++pEagWCveZUjKEn0zyUhBEXAMPLEjj//////////8BEXAMPLExODk2NDgyNzg1NSIMo1mWnpESWUoYw4BkKqEFSrm3DXuL8w+ZbVc4JKjDP4vUCKNR6Le9C9pZp9PsW0NoFy3vLBUdAXEXAMPLEOVG8feXfiEEA+1khgFK/wEtwR+9zF7NaMMMse07wN2gG2tH0eKMEXAMPLEQX+sMbytQo8iepP9PZOzlZsSFb/dP5Q8hk6YEXAMPLEYcKZsTkDAq2uKFQ8mYUVA9EtQnNRiFLEY83aKvG/tqLWNnGlSNVx7SMcfovkFDqQamm+88y1OwwAEYK7qcoceX6Z7GGcaYuIfGpaX2MCCELeQvZ+8WxEgOnIfz7GYvsYNjLZSaRnV4G+ILY1F0QNW64S9Nvj+BwDg3ht2CrNvpwjVYlj9U3nmxE0UG5ne83LL5hhqMpm25kmL7enVgw2kQzmU2id4IKu0C/WaoDRuO2F5zE63vJbxN8AYs7338+4B4HBb6BZ6OUgg96Q15RA41/gIqxaVPxyTpDfTU5GfSLxocdYeniqqpFMtZG2n9d0u7GsQNcFkNcG3qDZm4tDo8tZbuym0a2VcF2E5hFEgXBa+XLJCfXi/77OqAEjP0x7Qdk3B43p8KG/BaioP5RsV8zBGvH1zAgyPha2rN70/tT13yrmPd5QYEfwzexjKrV4mWIuRg8NTHYSZJUaeyCwTom80VFUJXG+GYTUyv5W22aBcnoRGiCiKEYTLOkgXecdKFTHmcIAejQ9Welr0a196Kq87w5KNMCkcCGFnwBNFLmfnbpNqT6rUBxxs3X5ntX9d8HVtSYINTsGXXMZCJ7fnbWajhg/aox0FtHX21eF6qIGT8j1z+l2opU+ggwUgkhUUgCH2TfqBj+MLMVVvpgqJsPKt582caFKArIFIvO+9QupxLnEH2hz04TMTfnU6bQC6z1buVe7h+tOLnh1YPFsLQ88anib/7TTC8k9DsBTq0ASe8R2GbSEsmO9qbbMwgEaYUhOKtGeyQsSJdhSk6XxXThrWL9EnwBCXDkICMqdntAxyyM9nWsZ4bL9JHqExgWUmfWChzPFAqn3F4y896UqHTZxlq3WGypn5HHcem2Hqf3IVxKH1inhqdVtkryEiTWrI7ZdjbqnqRbl+WgtPtKOOweDlCaRs3R2qXcbNgVhleMk4IWnF8D1695AenU1LwHjOJLkCjxgNFiWAFEPH9aEXAMPLExA==",
  "Authorization": "AWS4-HMAC-SHA256 Credential=XXXXXXXXXXXXXXXXXXX/20200401/us-east-1/appsync/aws4_request, SignedHeaders=accept;content-encoding;content-type;host;x-amz-date;x-amz-security-token, Signature=83EXAMPLEbcc1fe3ee69f75cd5ebbf4cb4f150e4f99cec869f149c5EXAMPLEdc"
}
```

**URL de solicitação com string de consulta**

```
wss://api.example.com/graphql?header=eyEXAMPLEHQiOiJhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L2phdmFEXAMPLEQiLCJjb250ZW50LWVuY29kaW5nIjoEXAMPLEEuMCIsImNvbnRlbnQtdHlwZSI6ImFwcGxpY2F0aW9EXAMPLE47IGNoYXJzZXQ9VVRGLTgiLCJob3N0IjoiZXhhbXBsZEXAMPLENjc4OTAwMDAuYXBwc3luYy1hcGkudXMtZWFzdC0xLmFtYEXAMPLEcy5jb20iLCJ4LWFtei1kYXRlIjoiMjAyMDA0MDFUMDAxMDEwWiIsIlgtEXAMPLElY3VyaXR5LVRva2VuIjoiQWdvSmIzSnBaMmx1WDJWakVBb2FEbUZ3TFhOdmRYUm9aV0Z6ZEMweUlrY3dSUUlnQWg5N0NsanE3d09QTDhLc3hQM1l0RHV5Yy85aEFqOFBoSjdGdmYzOFNnb0NJUURoSllKYkpsbmpQc3Bpb096dGorK3BFYWdXQ3ZlWlVqS0VuMHp5VWhCbXhpck5CUWpqLy8vLy8vLy8vLzhCRUFBYUREY3hPRGsyTkRneU56ZzFOU0lNbzFtV25wRVNXVW9ZdzRCa0txRUZTcm0zRFh1TDh3K1piVmM0SktqRFA0dlVDS05SNkxlOUM5cFpwOVBzVzBOb0Z5M3ZMQlVkQVh3dDZQSld1T1ZHOGZlWGZpRUVBKzFraGdGSy93RXR3Uis5ekY3TmFNTU1zZTA3d04yZ0cydEgwZUtNVFhuOEF3QVFYK3NNYnl0UW84aWVwUDlQWk96bFpzU0ZiL2RQNVE4aGs2WWpHVGFMMWVZY0tac1RrREFxMnVLRlE4bVlVVkE5RXRRbk5SaUZMRVk4M2FLdkcvdHFMV05uR2xTTlZ4N1NNY2ZvdmtGRHFRYW1tKzg4eTFPd3dBRVlLN3Fjb2NlWDZaN0dHY2FZdUlmR3BhWDJNQ0NFTGVRdlorOFd4RWdPbklmejdHWXZzWU5qTFpTYVJuVjRHK0lMWTFGMFFOVzY0UzlOdmorQndEZzNodDJDck52cHdqVllsajlVM25teEUwVUc1bmU4M0xMNWhocU1wbTI1a21MN2VuVmd3MmtRem1VMmlkNElLdTBDL1dhb0RSdU8yRjV6RTYzdkpieE44QVlzNzMzOCs0QjRIQmI2Qlo2T1VnZzk2UTE1UkE0MS9nSXF4YVZQeHlUcERmVFU1R2ZTTHhvY2RZZW5pcXFwRk10WkcybjlkMHU3R3NRTmNGa05jRzNxRFptNHREbzh0WmJ1eW0wYTJWY0YyRTVoRkVnWEJhK1hMSkNmWGkvNzdPcUFFalAweDdRZGszQjQzcDhLRy9CYWlvUDVSc1Y4ekJHdkgxekFneVBoYTJyTjcwL3RUMTN5cm1QZDVRWUVmd3pleGpLclY0bVdJdVJnOE5USFlTWkpVYWV5Q3dUb204MFZGVUpYRytHWVRVeXY1VzIyYUJjbm9SR2lDaUtFWVRMT2tnWGVjZEtGVEhtY0lBZWpROVdlbHIwYTE5NktxODd3NUtOTUNrY0NHRm53Qk5GTG1mbmJwTnFUNnJVQnh4czNYNW50WDlkOEhWdFNZSU5Uc0dYWE1aQ0o3Zm5iV2FqaGcvYW94MEZ0SFgyMWVGNnFJR1Q4ajF6K2wyb3BVK2dnd1Vna2hVVWdDSDJUZnFCaitNTE1WVnZwZ3FKc1BLdDU4MmNhRktBcklGSXZPKzlRdXB4TG5FSDJoejA0VE1UZm5VNmJRQzZ6MWJ1VmU3aCt0T0xuaDFZUEZzTFE4OGFuaWIvN1RUQzhrOURzQlRxMEFTZThSMkdiU0VzbU85cWJiTXdnRWFZVWhPS3RHZXlRc1NKZGhTazZYeFhUaHJXTDlFbndCQ1hEa0lDTXFkbnRBeHl5TTluV3NaNGJMOUpIcUV4Z1dVbWZXQ2h6UEZBcW4zRjR5ODk2VXFIVFp4bHEzV0d5cG41SEhjZW0ySHFmM0lWeEtIMWluaHFkVnRrcnlFaVRXckk3WmRqYnFucVJibCtXZ3RQdEtPT3dlRGxDYVJzM1IycVhjYk5nVmhsZU1rNElXbkY4RDE2OTVBZW5VMUx3SGpPSkxrQ2p4Z05GaVdBRkVQSDlhTklhcXMvWnhBPT0iLCJBdXRob3JpemF0aW9uIjoiQVdTNC1ITUFDLVNIQTI1NiBDcmVkZW50aWFsPVhYWFhYWFhYWFhYWFhYWFhYWFgvMjAxOTEwMDIvdXMtZWFzdC0xEXAMPLE5bmMvYXdzNF9yZXF1ZXN0LCBTaWduZWRIZWFkZXJzPWFjY2VwdDtjb250ZWEXAMPLE29kaW5nO2NvbnRlbnQtdHlwZTtob3EXAMPLEW16LWRhdGU7eC1hbXotc2VjdXJpdHktdG9rZW4sIFNpZ25hdHVyZT04MzE4EXAMPLEiY2MxZmUzZWU2OWY3NWNkEXAMPLE0Y2I0ZjE1MGU0Zjk5Y2VjODY5ZjE0OWM1ZDAzNDEXAMPLEn0=&payload=e30=
```

**nota**  
Uma WebSocket conexão pode ter várias assinaturas (mesmo com modos de autenticação diferentes). Uma forma de implementar isso é criar uma WebSocket conexão para a primeira assinatura e fechá-la quando a última assinatura não for registrada. Você pode otimizar isso aguardando alguns segundos antes de fechar a WebSocket conexão, caso o aplicativo seja inscrito imediatamente após o cancelamento do registro da última assinatura. Para um exemplo de aplicativo móvel, ao mudar de uma tela para outra, no evento de *desmontagem*, ele interrompe uma assinatura e, no evento de *montagem*, ele inicia uma assinatura diferente.

### Autorização do Lambda
<a name="lambda-auth"></a>

#### Cabeçalho de autorização do Lambda
<a name="lambda-auth-list"></a>

**Conteúdo do cabeçalho**
+  `"Authorization": <string>`: O valor que é passado como `authorizationToken`.
+  `"host": <string>`: o host do endpoint do AWS AppSync GraphQL ou do seu nome de domínio personalizado.

**Exemplo**

```
{
    "Authorization":"M0UzQzM1MkQtMkI0Ni00OTZCLUI1NkQtMUM0MTQ0QjVBRTczCkI1REEzRTIxLTk5NzItNDJENi1BQjMwLTFCNjRFNzQ2NzlCNQo=",
    "host":"example1234567890000.appsync-api.us-east-1.amazonaws.com"
}
```

**Cabeçalhos por meio da string de consulta**

Primeiro, um objeto JSON contendo o `host` e o `Authorization` é convertido em uma string. Em seguida, essa string é codificada usando a codificação base64. A string codificada em base64 resultante é adicionada como um parâmetro de consulta nomeado `header` ao WebSocket URL para estabelecer a conexão com o AWS AppSync endpoint em tempo real. A URL da solicitação resultante assume a seguinte forma:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql?header=eyJBdXRob3JpemF0aW9uIjoiZXlKcmFXUWlPaUpqYkc1eGIzQTVlVzVNSzA5UVlYSXJNVEpIV0VGTFNYQmllVTVXTkhoc1FqaFBWVzlZTW5NMldsZHZQU0lzSW1Gc1p5STZJbEpUTWpVMkluMC5leUp6ZFdJaU9pSmhObU5tTWpjd055MHhOamd4TFRRMU5ESXRPV1l4T0MxbE5qWTBNVGcyTmpsa016WWlMQ0psZG1WdWRGOXBaQ0k2SW1Wa016TTVNbU5rTFdOallUTXROR00yT0MxaE5EWXlMVEpsWkdJM1pUTm1ZMkZqWmlJc0luUnZhMlZ1WDNWelpTSTZJbUZqWTJWemN5SXNJbk5qYjNCbElqb2lZWGR6TG1OdloyNXBkRzh1YzJsbmJtbHVMblZ6WlhJdVlXUnRhVzRpTENKaGRYUm9YM1JwYldVaU9qRTFOamswTlRjM01UZ3NJbWx6Y3lJNkltaDBkSEJ6T2x3dlhDOWpiMmR1YVhSdkxXbGtjQzVoY0MxemIzVjBhR1ZoYzNRdE1pNWhiV0Y2YjI1aGQzTXVZMjl0WEM5aGNDMXpiM1YwYUdWaGMzUXRNbDgzT0hZMFNWWmliVkFpTENKbGVIQWlPakUxTmprME5qRXpNakFzSW1saGRDSTZNVFUyT1RRMU56Y3lNQ3dpYW5ScElqb2lOVGd6WmpobVltTXRNemsyTVMwMFl6QTRMV0poWlRBdFl6UXlZMkl4TVRNNU5EWTVJaXdpWTJ4cFpXNTBYMmxrSWpvaU0zRmxhalZsTVhabU16ZDFOM1JvWld3MGRHOTFkREprTVd3aUxDSjFjMlZ5Ym1GdFpTSTZJbVZzYjNKNllXWmxJbjAuQjRjZEp0aDNLRk5wSjZpa1ZwN2U2RFJlZTk1VjZRaS16RUUyREpIN3NIT2wyenhZaTdmLVNtRUdvaDJBRDhlbXhRUllhakJ5ei1yRTRKaDBRT3ltTjJZcy1aSWtNcFZCVFBndS1UTVdEeU9IaERVbVVqMk9QODJ5ZVozd2xaQXRyX2dNNEx6alhVWG1JX0syeUdqdVhmWFRhYTFtdlFFQkcwbVFmVmQ3U2Z3WEItamN2NFJZVmk2ajI1cWdvdzlFdzUydWZ1clBxYUstM1dBS0czMktwVjhKNC1XZWpxOHQwYy15QTdzYjhFbkI1NTFiN1RVOTN1S1JpVlZLM0U1NU5rNUFEUG9hbV9XWUU0NWkzczVxVkFQXy1Jblc3NU5Vb09DR1RzUzhZV01mYjZlY0hZSi0xai1iekEyN3phVDlWamN0WG45YnlORlptS0xwQTJMY3h3IiwiaG9zdCI6ImV4YW1wbGUxMjM0NTY3ODkwMDAwLmFwcHN5bmMtYXBpLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tIn0=&payload=e30=
```

É importante observar que, além do objeto de cabeçalho codificado em base64, um objeto JSON vazio \$1\$1 também é codificado em base64 e incluído como um parâmetro de consulta separado nomeado na URL. `payload` WebSocket

**Cabeçalhos por meio de `Sec-WebSocket-Protocol`**

Um objeto JSON contendo o `host` e o `Authorization` é convertido em uma string e, em seguida, codificado usando a codificação base64Url. A string codificada em base64Url resultante é prefixada com `header-`. Essa string prefixada é então usada como um novo subprotocolo, além do `Sec-WebSocket-Protocol` cabeçalho, ao `graphql-ws` estabelecer a WebSocket conexão com o endpoint AWS AppSync em tempo real. 

A URL da solicitação resultante assume a seguinte forma:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

O cabeçalho `Sec-WebSocket-Protocol` contém o seguinte valor:

```
"sec-websocket-protocol" : ["graphql-ws", "header-ewogICAgImhvc3QiOiJleGFtcGxlMTIzNDU2Nzg5MDAwMC5hcHBzeW5jLWFwaS51cy1lYXN0LTEuYW1hem9uYXdzLmNvbSIsCiAgICAieC1hcGkta2V5IjoiZGEyLTEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Igp9"]
```

**Cabeçalhos por meio de cabeçalhos HTTP padrão**

Nesse método, as informações do host e da autorização são transmitidas usando cabeçalhos HTTP padrão ao estabelecer a WebSocket conexão com o endpoint AWS AppSync em tempo real. A URL da solicitação resultante assume a seguinte forma:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

Os cabeçalhos de solicitação incluiriam o seguinte:

```
"sec-websocket-protocol" : ["graphql-ws"]
"Authorization":"eyEXAMPLEiJjbG5xb3A5eW5MK09QYXIrMTJHWEFLSXBieU5WNHhsQjEXAMPLEnM2WldvPSIsImFsZyI6IlEXAMPLEn0.eyEXAMPLEiJhNmNmMjcwNy0xNjgxLTQ1NDItOWYxOC1lNjY0MTg2NjlkMzYiLCJldmVudF9pZCI6ImVkMzM5MmNkLWNjYTMtNGM2OC1hNDYyLTJlZGI3ZTNmY2FjZiIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoiYXdzLmNvZ25pdG8uc2lnbmluLnVzZXIuYWRtaW4iLCJhdXRoX3RpbWUiOjE1Njk0NTc3MTgsImlzcyI6Imh0dHBzOlwvXC9jb2duaXRvLWlkcC5hcC1zb3V0aGVhc3QtMi5hbWF6b25hd3MuY29tXC9hcC1zb3V0aGVhc3QtMl83OHY0SVZibVAiLCJleHAiOjE1Njk0NjEzMjAsImlhdCI6MTU2OTQ1NzcyMCwianRpIjoiNTgzZjhmYmMtMzk2MS00YzA4LWJhZTAtYzQyY2IxMTM5NDY5IiwiY2xpZW50X2lkIjoiM3FlajVlMXZmMzd1N3RoZWw0dG91dDJkMWwiLCJ1c2VybmFtZSI6ImVsb3EXAMPLEn0.B4EXAMPLEFNpJ6ikVp7e6DRee95V6Qi-zEE2DJH7sHOl2zxYi7f-SmEGoh2AD8emxQRYajByz-rE4Jh0QOymN2Ys-ZIkMpVBTPgu-TMWDyOHhDUmUj2OP82yeZ3wlZAtr_gM4LzjXUXmI_K2yGjuXfXTaa1mvQEBG0mQfVd7SfwXB-jcv4RYVi6j25qgow9Ew52ufurPqaK-3WAKG32KpV8J4-Wejq8t0c-yA7sb8EnB551b7TU93uKRiVVK3E55Nk5ADPoam_WYE45i3s5qVAP_-InW75NUoOCGTsS8YWMfb6ecHYJ-1j-bzA27zaT9VjctXn9byNFZmEXAMPLExw",
"host":"example1234567890000.appsync-api.us-east-1.amazonaws.com"
```

## WebSocket Operação em tempo real
<a name="real-time-websocket-operation"></a>

Depois de iniciar um WebSocket handshake bem-sucedido com AWS AppSync, o cliente deve enviar uma mensagem subsequente à qual se conectar AWS AppSync para diferentes operações. Essas mensagens exigem os seguintes dados:
+  `type`: O tipo da operação.
+  `id`: Um identificador exclusivo para a assinatura. Recomendamos usar um UUID para esse fim.
+  `payload`: A carga associada dependendo do tipo de operação.

O campo `type` é o único campo obrigatório; os campos `id` e `payload` são opcionais.

### Sequência de eventos
<a name="sequence-of-events"></a>

Para iniciar, estabelecer, registrar e processar com êxito a solicitação de assinatura, o cliente deve percorrer a seguinte sequência:

1. Inicializar conexão (`connection_init`)

1. Confirmação de conexão (`connection_ack`)

1. Registro de assinatura (`start`)

1. Confirmação de assinatura (`start_ack`)

1. Processamento de assinatura (`data`)

1. Cancelamento de registro de assinatura (`stop`)

## Mensagem de inicialização de conexão
<a name="connection-init-message"></a>

(Opcional) Depois de um aperto de mão bem-sucedido, o cliente pode enviar a `connection_init` mensagem para começar a se comunicar com o endpoint AWS AppSync em tempo real. A mensagem é uma string obtida quando se coloca em string o seguinte objeto JSON assim:

```
{ "type": "connection_init" }
```

## Mensagem de confirmação de conexão
<a name="connection-acknowledge-message"></a>

Depois de enviar a mensagem `connection_init`, o cliente deve aguardar a mensagem `connection_ack`. Todas as mensagens enviadas antes de receber `connection_ack` são ignoradas. A mensagem deve ser a seguinte:

```
{
  "type": "connection_ack",
  "payload": {
    // Time in milliseconds waiting for ka message before the client should terminate the WebSocket connection
    "connectionTimeoutMs": 300000
  }
}
```

## Mensagem keep-alive
<a name="keep-alive-message"></a>

Além da mensagem de confirmação de conexão, o cliente recebe mensagens keep-alive periodicamente. Se o cliente não receber uma mensagem de manutenção de atividade dentro do período de tempo limite da conexão, ele deverá fechar a conexão. AWS AppSync continua enviando essas mensagens e atendendo às assinaturas registradas até encerrar a conexão automaticamente (após 24 horas). As mensagens keep-alive são heartbeats e não precisam ser confirmadas pelo cliente.

```
{ "type": "ka" }
```

## Mensagem de registro de assinatura
<a name="subscription-registration-message"></a>

Depois que o cliente recebe uma `connection_ack` mensagem, ele pode enviar mensagens de registro de assinatura para AWS AppSync. Esse tipo de mensagem é um objeto JSON em string que contém os seguintes campos:
+  `"id": <string>`: O nome da assinatura. Esse ID deve ser exclusivo para cada assinatura, caso contrário, o servidor retornará um erro indicando que o ID da assinatura está duplicado.
+  `"type": "start"`: Um parâmetro `<string>` constante.
+  `"payload": <Object>`: Um objeto que contém as informações relevantes para a assinatura.
  +  `"data": <string>`: Um objeto JSON em string que contém variáveis e consulta do GraphQL.
    +  `"query": <string>`: Uma operação do GraphQL.
    +  `"variables": <Object>`: Um objeto que contém as variáveis para a consulta.
  +  `"extensions": <Object>`: Um objeto que contém um objeto de autorização.
+  `"authorization": <Object>`: Um objeto que contém os campos necessários para autorização.

### Objeto de autorização para registro de assinatura
<a name="authorization-object-for-subscription-registration"></a>

As mesmas regras na seção [Formato do parâmetro de cabeçalho com base no modo de autorização AWS AppSync da API](#header-parameter-format-based-on-appsync-api-authorization-mode) se aplicam ao objeto de autorização. A única exceção é o IAM, no qual as informações de assinatura do SigV4 são um pouco diferentes. Para obter mais detalhes, consulte o exemplo do IAM.

Exemplo usando grupos de usuários do Amazon Cognito:

```
{
  "id": "ee849ef0-cf23-4cb8-9fcb-152ae4fd1e69",
  "payload": {
    "data": "{\"query\":\"subscription onCreateMessage {\\n onCreateMessage {\\n __typename\\n message\\n }\\n }\",\"variables\":{}}",
      "extensions": {
        "authorization": {
          "Authorization": "eyEXAMPLEiJjbG5xb3A5eW5MK09QYXIrMTJEXAMPLEBieU5WNHhsQjhPVW9YMnM2WldvPSIsImFsZyI6IlEXAMPLEn0.eyJzdWIiOiJhNmNmMjcwNy0xNjgxLTQ1NDItEXAMPLENjY0MTg2NjlkMzYiLCJldmVudF9pZCI6ImU3YWVmMzEyLWUEXAMPLEY0Zi04YjlhLTRjMWY5M2Q5ZTQ2OCIsInRva2VuX3VzZSI6ImFjY2VzcyIsIEXAMPLEIjoiYXdzLmNvZ25pdG8uc2lnbmluLnVzZXIuYWRtaW4iLCJhdXRoX3RpbWUiOjE1Njk2MTgzMzgsImlzcyI6Imh0dEXAMPLEXC9jb2duaXRvLWlkcC5hcC1zb3V0aGVhc3QtMi5hbWF6b25hd3MuY29tXC9hcC1zbEXAMPLEc3QtMl83OHY0SVZibVAiLCJleHAiOjE1NzAyNTQ3NTUsImlhdCI6MTU3MDI1MTE1NSwianRpIjoiMmIEXAMPLEktZTVkMi00ZDhkLWJiYjItNjA0YWI4MDEwOTg3IiwiY2xpZW50X2lkIjoiM3FlajVlMXZmMzd1EXAMPLE0dG91dDJkMWwiLCJ1c2VybmFtZSI6ImVsb3J6YWZlIn0.CT-qTCtrYeboUJ4luRSTPXaNewNeEXAMPLE14C6sfg05tO0fOMpiUwj9k19gtNCCMqoSsjtQoUweFnH4JYa5EXAMPLEVxOyQEQ4G7jQrt5Ks6STn53vuseR3zRW9snWgwz7t3ZmQU-RWvW7yQU3sNQRLEXAMPLEcd0yufBiCYs3dfQxTTdvR1B6Wz6CD78lfNeKqfzzUn2beMoup2h6EXAMPLE4ow8cUPUPvG0DzRtHNMbWskjPanu7OuoZ8iFO_Eot9kTtAlVKYoNbWkZhkD8dxutyoU4RSH5JoLAnrGF5c8iKgv0B2dfEXAMPLEIihxaZVJ9w9w48S4EXAMPLEcA",
          "host": "example1234567890000.appsync-api.us-east-1.amazonaws.com"
         }
      }
  },
  "type": "start"
}
```

Exemplo usando o IAM:

```
{
  "id": "eEXAMPLE-cf23-1234-5678-152EXAMPLE69",
  "payload": {
    "data": "{\"query\":\"subscription onCreateMessage {\\n onCreateMessage {\\n __typename\\n message\\n }\\n }\",\"variables\":{}}",
    "extensions": {
      "authorization": {
        "accept": "application/json, text/javascript",
        "content-type": "application/json; charset=UTF-8",
        "X-Amz-Security-Token": "AgEXAMPLEZ2luX2VjEAoaDmFwLXNvdXRoZWFEXAMPLEcwRQIgAh97Cljq7wOPL8KsxP3YtDuyc/9hAj8PhJ7Fvf38SgoCIQDhJEXAMPLEPspioOztj++pEagWCveZUjKEn0zyUhBEXAMPLEjj//////////8BEXAMPLExODk2NDgyNzg1NSIMo1mWnpESWUoYw4BkKqEFSrm3DXuL8w+ZbVc4JKjDP4vUCKNR6Le9C9pZp9PsW0NoFy3vLBUdAXEXAMPLEOVG8feXfiEEA+1khgFK/wEtwR+9zF7NaMMMse07wN2gG2tH0eKMEXAMPLEQX+sMbytQo8iepP9PZOzlZsSFb/dP5Q8hk6YEXAMPLEYcKZsTkDAq2uKFQ8mYUVA9EtQnNRiFLEY83aKvG/tqLWNnGlSNVx7SMcfovkFDqQamm+88y1OwwAEYK7qcoceX6Z7GGcaYuIfGpaX2MCCELeQvZ+8WxEgOnIfz7GYvsYNjLZSaRnV4G+ILY1F0QNW64S9Nvj+BwDg3ht2CrNvpwjVYlj9U3nmxE0UG5ne83LL5hhqMpm25kmL7enVgw2kQzmU2id4IKu0C/WaoDRuO2F5zE63vJbxN8AYs7338+4B4HBb6BZ6OUgg96Q15RA41/gIqxaVPxyTpDfTU5GfSLxocdYeniqqpFMtZG2n9d0u7GsQNcFkNcG3qDZm4tDo8tZbuym0a2VcF2E5hFEgXBa+XLJCfXi/77OqAEjP0x7Qdk3B43p8KG/BaioP5RsV8zBGvH1zAgyPha2rN70/tT13yrmPd5QYEfwzexjKrV4mWIuRg8NTHYSZJUaeyCwTom80VFUJXG+GYTUyv5W22aBcnoRGiCiKEYTLOkgXecdKFTHmcIAejQ9Welr0a196Kq87w5KNMCkcCGFnwBNFLmfnbpNqT6rUBxxs3X5ntX9d8HVtSYINTsGXXMZCJ7fnbWajhg/aox0FtHX21eF6qIGT8j1z+l2opU+ggwUgkhUUgCH2TfqBj+MLMVVvpgqJsPKt582caFKArIFIvO+9QupxLnEH2hz04TMTfnU6bQC6z1buVe7h+tOLnh1YPFsLQ88anib/7TTC8k9DsBTq0ASe8R2GbSEsmO9qbbMwgEaYUhOKtGeyQsSJdhSk6XxXThrWL9EnwBCXDkICMqdntAxyyM9nWsZ4bL9JHqExgWUmfWChzPFAqn3F4y896UqHTZxlq3WGypn5HHcem2Hqf3IVxKH1inhqdVtkryEiTWrI7ZdjbqnqRbl+WgtPtKOOweDlCaRs3R2qXcbNgVhleMk4IWnF8D1695AenU1LwHjOJLkCjxgNFiWAFEPH9aEXAMPLExA==",
        "Authorization": "AWS4-HMAC-SHA256 Credential=XXXXXXXXXXXXXXXXXXXX/20200401/us-east-1/appsync/aws4_request, SignedHeaders=accept;content-encoding;content-type;host;x-amz-date;x-amz-security-token, Signature=b90131a61a7c4318e1c35ead5dbfdeb46339a7585bbdbeceeaff51f4022eb1fd",
        "content-encoding": "amz-1.0",
        "host": "example1234567890000.appsync-api.us-east-1.amazonaws.com",
        "x-amz-date": "20200401T001010Z"
      }
    }
  },
  "type": "start"
}
```

Exemplo do uso de um nome de domínio personalizado:

```
{
  "id": "key-cf23-4cb8-9fcb-152ae4fd1e69",
  "payload": {
    "data": "{\"query\":\"subscription onCreateMessage {\\n onCreateMessage {\\n __typename\\n message\\n }\\n }\",\"variables\":{}}",
      "extensions": {
        "authorization": {
          "x-api-key": "da2-12345678901234567890123456",
          "host": "api.example.com"
         }
      }
  },
  "type": "start"
}
```

A assinatura do SigV4 não exige que `/connect` seja anexado ao URL, e a operação do GraphQL em string do JSON substitui `data`. Veja a seguir um exemplo de uma solicitação de assinatura do SigV4:

```
{
  url: "https://example1234567890000.appsync-api.us-east-1.amazonaws.com/graphql",
  data: "{\"query\":\"subscription onCreateMessage {\\n onCreateMessage {\\n __typename\\n message\\n }\\n }\",\"variables\":{}}",
  method: "POST",
  headers: {
    "accept": "application/json, text/javascript",
    "content-encoding": "amz-1.0",
    "content-type": "application/json; charset=UTF-8",
  }
}
```

## Mensagem de confirmação de assinatura
<a name="subscription-acknowledge-message"></a>

Depois de enviar a mensagem de início da assinatura, o cliente deve AWS AppSync aguardar o envio da `start_ack` mensagem. A mensagem `start_ack` indica que a assinatura foi bem-sucedida.

Exemplo de confirmação de assinatura:

```
{
  "type": "start_ack",
  "id": "eEXAMPLE-cf23-1234-5678-152EXAMPLE69"
}
```

## Mensagem de erro
<a name="error-message"></a>

Se a inicialização da conexão ou o registro da assinatura falhar, ou se uma assinatura for encerrada no servidor, o servidor enviará uma mensagem de erro para o cliente. Se o erro acontecer durante o tempo de inicialização da conexão, a conexão será fechada pelo servidor.
+  `"type": "error"`: Um parâmetro `<string>` constante.
+  `"id": <string>`: O ID da assinatura registrada correspondente, se relevante.
+  `"payload" <Object>`: Um objeto que contém as informações de erro correspondentes.

Exemplo:

```
{
  "type": "error",
  "payload": {
    "errors": [
      {
        "errorType": "LimitExceededError",
        "message": "Rate limit exceeded"
      }
    ]
  }
}
```

## Processar mensagens de dados
<a name="processing-data-messages"></a>

Quando um cliente envia uma mutação, AWS AppSync identifica todos os assinantes interessados nela e envia uma `"type":"data"` mensagem para cada um usando a assinatura correspondente da operação `id` de assinatura. `"start"` Espera-se que o cliente mantenha o controle do `id` de assinatura enviado para que, quando uma mensagem de dados for recebida, o cliente possa combiná-lo com a assinatura correspondente.
+  `"type": "data"`: Um parâmetro `<string>` constante.
+  `"id": <string>`: O ID da assinatura registrada correspondente.
+  `"payload" <Object>`: Um objeto que contém as informações da assinatura.

Exemplo:

```
{
  "type": "data",
  "id": "ee849ef0-cf23-4cb8-9fcb-152ae4fd1e69",
  "payload": {
    "data": {
      "onCreateMessage": {
        "__typename": "Message",
        "message": "test"
      }
    }
  }
}
```

## Mensagem de cancelamento de registro de assinatura
<a name="subscription-unregistration-message"></a>

Quando o aplicativo deseja parar de receber os eventos de assinatura, o cliente deve enviar uma mensagem com o seguinte objeto JSON em string:
+  `"type": "stop"`: Um parâmetro `<string>` constante.
+  `"id": <string>`: O ID da assinatura com registro cancelado.

Exemplo:

```
{
  "type":"stop",
  "id":"ee849ef0-cf23-4cb8-9fcb-152ae4fd1e69"
}
```

AWS AppSync envia de volta uma mensagem de confirmação com o seguinte objeto JSON stringificado:
+  `"type": "complete"`: Um parâmetro `<string>` constante.
+  `"id": <string>`: O ID da assinatura com registro cancelado.

Depois que o cliente recebe a mensagem de confirmação, ele não recebe mais mensagens para essa assinatura específica.

Exemplo:

```
{
  "type":"complete",
  "id":"eEXAMPLE-cf23-1234-5678-152EXAMPLE69"
}
```

## Desconectando o WebSocket
<a name="disconnecting-the-websocket"></a>

Antes de se desconectar, para evitar perda de dados, o cliente deve ter a lógica necessária para verificar se nenhuma operação está sendo realizada atualmente por meio da WebSocket conexão. Todas as assinaturas devem ser canceladas antes de se desconectar do. WebSocket

# Mesclando em APIs AWS AppSync
<a name="merged-api"></a>

À medida que o uso do GraphQL se expande dentro de uma organização, podem surgir compensações entre a API e a velocidade de desenvolvimento da API ease-of-use. Por um lado, as organizações adotam AWS AppSync o GraphQL para simplificar o desenvolvimento de aplicativos. Isso oferece aos desenvolvedores uma API flexível que eles podem usar para acessar, manipular e combinar com segurança dados de um ou mais domínios de dados com uma única chamada de rede. Por outro lado, as equipes de uma organização responsáveis pelos diferentes domínios de dados combinados em um único endpoint da API GraphQL podem querer a capacidade de criar, gerenciar e implantar atualizações de API independentes umas das outras. Isso aumenta suas velocidades de desenvolvimento. 

Para resolver essa tensão, o APIs recurso AWS AppSync Merged permite que equipes de diferentes domínios de dados criem e implantem de forma independente AWS AppSync APIs (por exemplo, esquemas, resolvedores, fontes de dados e funções do GraphQL), que podem então ser combinadas em uma única API mesclada. Isso dá às organizações a capacidade de manter uma API multidomínio simples de usar, e uma forma de as diferentes equipes que contribuem com essa API poderem fazer atualizações de API de forma rápida e independente.

O diagrama a seguir mostra o fluxo de trabalho da API mesclada:

![\[Diagrama mostrando o fluxo de trabalho da API mesclada com várias fontes APIs sendo combinadas em um único endpoint de API mesclada\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/images/merged-api-workflow.png)


Usando o Merged APIs, as organizações podem importar os recursos de várias fontes independentes AWS AppSync APIs em um único endpoint de API AWS AppSync mesclada. Para fazer isso, você AWS AppSync pode criar uma lista de fontes e AWS AppSync APIs, em seguida, mesclar todos os metadados associados à fonte, APIs incluindo esquema, tipos, fontes de dados, resolvedores e funções, em uma nova API mesclada. AWS AppSync 

Durante as mesclagens, existe a possibilidade de ocorrer um conflito de mesclagem devido a inconsistências no conteúdo dos dados da API de origem, como conflitos de nomenclatura de tipos ao combinar vários esquemas. Para casos de uso simples em que nenhuma definição na fonte está em APIs conflito, não há necessidade de modificar os esquemas da API de origem. A API mesclada resultante simplesmente importa todos os tipos, resolvedores, fontes de dados e funções da fonte original. AWS AppSync APIs Para casos de uso complexos em que surjam conflitos, eles users/teams terão que resolvê-los por vários meios. AWS AppSync fornece aos usuários várias ferramentas e exemplos que podem reduzir os conflitos de mesclagem. 

As mesclagens subsequentes configuradas no AWS AppSync propagarão as alterações feitas na fonte APIs para a API mesclada associada.

## Fusão APIs e federação
<a name="merged-api-federation"></a>

Há muitas soluções e padrões na comunidade GraphQL para combinar esquemas do GraphQL e permitir a colaboração em equipe por meio de um gráfico compartilhado. AWS AppSync O Merged APIs adota uma abordagem de *tempo de construção* para a composição do esquema, em que APIs as fontes são combinadas em uma API mesclada separada. Uma abordagem alternativa é colocar um roteador em camadas em *tempo de execução* em várias fontes APIs ou subgráficos. Nessa abordagem, o roteador recebe uma solicitação, faz referência a um esquema combinado que ele mantém como metadados, constrói um plano de solicitação e, em seguida, distribui os elementos da solicitação em seus subgráficos/servidores subjacentes. A tabela a seguir compara a abordagem de tempo de construção da API AWS AppSync mesclada com abordagens de tempo de execução baseadas em roteador para a composição do esquema GraphQL:


|  |  |  | 
| --- |--- |--- |
| Recurso | AppSync API mesclada | Soluções baseadas em roteadores | 
| Subgráficos gerenciados de maneira independente | Sim | Sim | 
| Subgráficos endereçáveis de forma independente | Sim | Sim | 
| Composição automatizada do esquema | Sim | Sim | 
| Detecção automatizada de conflitos | Sim | Sim | 
| Resolução de conflitos por meio de diretivas de esquema | Sim | Sim | 
| Servidores de subgráficos compatíveis | AWS AppSync\$1 | Varia | 
| Complexidade da rede | Uma API única e mesclada significa que não há saltos extras na rede. | A arquitetura multicamada requer planejamento e delegação de consultas, análise e serialização/desserialização de subconsultas e resolvedores de referência em subgráficos para realizar junções. | 
| Suporte de observabilidade | Monitoramento, registro e rastreamento integrados. Um único servidor de API mesclado significa depuração simplificada. | Build-your-own observabilidade no roteador e em todos os servidores de subgráficos associados. Depuração complexa em sistemas distribuídos. | 
| Suporte de autorização | Suporte integrado para vários modos de autorização. | Build-your-own regras de autorização. | 
| Segurança entre contas | Suporte integrado para associações de contas entre AWS nuvens. | Build-your-own modelo de segurança. | 
| Suporte para assinaturas | Sim | Não | 

\$1 O AWS AppSync mesclado só APIs pode ser associado à AWS AppSync fonte APIs. Se precisar de suporte para composição de esquemas entre AWS AppSync e sem AWS AppSync subgráficos, você pode conectar um ou mais GraphQL and/or APIs Merged em uma solução AWS AppSync baseada em roteador. [Por exemplo, consulte o blog de referência para adicionar AWS AppSync APIs como subgráfico usando uma arquitetura baseada em roteador com o Apollo Federation v2: Apollo GraphQL Federation with. AWS AppSync](https://aws.amazon.com/blogs/mobile/federation-appsync-subgraph/) 

**Topics**
+ [Fusão APIs e federação](#merged-api-federation)
+ [Resolução de conflitos de API mesclada](#merged-api-conflict-resolution)
+ [Configurar esquemas](#configuring-schemas-merged-api)
+ [Configurar modos de autorização](#configuring-authorization-merged-api)
+ [Configurar perfis de execução](#execution-roles-merged-api)
+ [Configurando contas cruzadas mescladas usando APIs AWS RAM](#cross-account-merged-api)
+ [Mesclar](#merges)
+ [Suporte adicional para Merged APIs](#merge-api-additional-support)
+ [Limitações de APIs mescladas](#merged-api-limits)
+ [Considerações sobre a API mesclada](#merged-api-considerations)
+ [Criando mesclado APIs](#creating-merged-api)

## Resolução de conflitos de API mesclada
<a name="merged-api-conflict-resolution"></a>

No caso de um conflito de mesclagem, AWS AppSync fornece aos usuários várias ferramentas e exemplos para ajudar a solucionar o (s) problema (s).

### Diretivas de esquema de API mescladas
<a name="merged-api-schema-directive"></a>

 AWS AppSync introduziu várias diretivas do GraphQL que podem ser usadas para reduzir ou resolver conflitos na fonte: APIs
+ *@canonical*: essa diretiva define a precedência de tipos/campos com nomes e dados semelhantes. Se duas ou mais fontes APIs tiverem o mesmo tipo ou campo do GraphQL, uma delas APIs poderá anotar seu tipo ou campo como *canônico*, o que será priorizado durante a mesclagem. Os conflitos types/fields que não estão anotados com esta diretiva em outra fonte APIs são ignorados quando mesclados. 
+ *@hidden*: Esta diretiva encapsula certos types/fields para removê-los do processo de fusão. As equipes podem querer remover ou ocultar tipos ou operações específicos na API de origem para que somente clientes internos possam acessar dados digitados específicos. Com essa diretiva anexada, os tipos ou campos não são mesclados na API mesclada. 
+ *@renamed*: Essa diretiva altera os nomes de types/fields para reduzir os conflitos de nomenclatura. Há situações em que diferentes APIs têm o mesmo tipo ou nome de campo. No entanto, todos eles precisam estar disponíveis no esquema mesclado. Uma maneira simples de incluir todos eles na API mesclada é renomear o campo para algo semelhante, mas diferente. 

Para mostrar o esquema de utilitário fornecido pelas diretivas, considere o seguinte exemplo:

Neste exemplo, vamos supor que queremos mesclar duas fontes APIs. Temos dois esquemas que criam e recuperam postagens (por exemplo, seção de comentários ou postagens em mídias sociais). Supondo que os tipos e campos sejam muito semelhantes, há uma grande chance de conflito durante uma operação de mesclagem. Os trechos abaixo mostram os tipos e campos de cada esquema.

O primeiro arquivo, chamado *Source1.graphql*, é um esquema do GraphQL que permite ao usuário criar `Posts`usando a mutação `putPost`. Cada `Post` contém um título e um ID. O ID é usado para referenciar as informações do autor ou do `User` (e-mail e endereço) e a `Message`, ou a carga útil (conteúdo). O tipo `User` é anotado com a tag *@canonical*.

```
# This snippet represents a file called Source1.graphql

type Mutation {
    putPost(id: ID!, title: String!): Post
}

type Post {
    id: ID!
    title: String!
}

type Message {
   id: ID!
   content: String
}

type User @canonical {
   id: ID!
   email: String!
   address: String!
}

type Query {
    singlePost(id: ID!): Post
    getMessage(id: ID!): Message
}
```

O segundo arquivo, chamado *Source2.graphql*, é um esquema do GraphQL que funciona muito semelhante ao *Source1.graphql*. No entanto, observe que os campos de cada tipo são diferentes. Ao mesclar esses dois esquemas, haverá conflitos de mesclagem devido a essas diferenças. 

Além disso, observe como o *Source2.graphql* também contém várias diretivas para reduzir esses conflitos. O tipo `Post` é anotado com uma tag *@hidden* para se ofuscar durante a operação de mesclagem. O tipo `Message` é anotado com a tag *@renamed* para modificar o nome do tipo `ChatMessage` no caso de um conflito de nomenclatura com outro tipo `Message`.

```
# This snippet represents a file called Source2.graphql

type Post @hidden  {
    id: ID!
    title: String!
    internalSecret: String!
}

type Message @renamed(to: "ChatMessage") {
   id: ID!
   chatId: ID!
   from: User!
   to: User!
}

# Stub user so that we can link the canonical definition from Source1
type User {
   id: ID!
}

type Query {
    getPost(id: ID!): Post
    getMessage(id: ID!): Message @renamed(to: "getChatMessage")
}
```

Quando a mesclagem ocorrer, o resultado produzirá o arquivo `MergedSchema.graphql`:

```
# This snippet represents a file called MergedSchema.graphql

type Mutation {
    putPost(id: ID!, title: String!): Post
}

# Post from Source2 was hidden so only uses the Source1 definition. 
type Post {
    id: ID!
    title: String!
}

# Renamed from Message to resolve the conflict
type ChatMessage {
   id: ID!
   chatId: ID!
   from: User!
   to: User!
}

type Message {
   id: ID!
   content: String
}

# Canonical definition from Source1
type User {
   id: ID!
   email: String!
   address: String!
}

type Query {
    singlePost(id: ID!): Post
    getMessage(id: ID!): Message
    
    # Renamed from getMessage
    getChatMessage(id: ID!): ChatMessage
}
```

Várias coisas ocorreram na mesclagem:
+ O tipo `User` de *Source1.graphql* foi priorizado em relação a `User` de *Source2.graphql* por causa da anotação *@canonical*.
+ O `Message` tipo do *Source1.graphql* foi incluído na mesclagem. No entanto, o `Message` do *source2.graphql* teve um conflito de nomenclatura. Devido à anotação *@renamed*, ele também foi incluído na mesclagem, mas com o nome alternativo `ChatMessage`.
+ O tipo `Post` de *Source1.graphql* foi incluído, mas o tipo `Post` de *Source2.graphql* não. Normalmente, haveria um conflito nesse tipo, mas como o tipo `Post` de *Source2.graphql* tinha uma anotação *@hidden*, seus dados foram ofuscados e não incluídos na mesclagem. Isso não resultou em conflitos.
+ O tipo `Query` foi atualizado para incluir o conteúdo dos dois arquivos. No entanto, uma consulta `GetMessage` foi renomeada para `GetChatMessage` devido à diretiva. Isso resolveu o conflito de nomenclatura entre as duas consultas com o mesmo nome.

Também existe o caso de nenhuma diretiva ser adicionada a um tipo conflitante. Nesse caso, o tipo mesclado incluirá a união de todos os campos de todas as definições de origem desse tipo. Por exemplo, considere o exemplo a seguir:

Esse esquema, chamado *Source1.graphql*, permite criar e recuperar `Posts`. A configuração é semelhante à do exemplo anterior, mas com menos informações.

```
# This snippet represents a file called Source1.graphql

type Mutation {
    putPost(id: ID!, title: String!): Post
}

type Post  {
    id: ID!
    title: String!
}

type Query {
    getPost(id: ID!): Post
}
```

Esse esquema, chamado *Source2.graphql*, permite criar e recuperar `Reviews` (por exemplo, classificação de filmes ou resenhas de restaurantes). As `Reviews` estão associadas ao `Post` do mesmo valor de ID. Juntos, eles contêm o título, o ID da postagem e a mensagem da payload da postagem de avaliação completa.

Ao mesclar, haverá um conflito entre os dois tipos de `Post`. Como não há anotações para resolver esse problema, o comportamento padrão é realizar uma operação de união nos tipos conflitantes.

```
# This snippet represents a file called Source2.graphql

type Mutation {
    putReview(id: ID!, postId: ID!, comment: String!): Review
}

type Post  {
    id: ID!
    reviews: [Review]
}

type Review {
   id: ID!
   postId: ID!
   comment: String!
}

type Query {
    getReview(id: ID!): Review
}
```

Quando a mesclagem ocorrer, o resultado produzirá o arquivo `MergedSchema.graphql`:

```
# This snippet represents a file called MergedSchema.graphql

type Mutation {
    putReview(id: ID!, postId: ID!, comment: String!): Review
    putPost(id: ID!, title: String!): Post
}

type Post  {
    id: ID!
    title: String!
    reviews: [Review]
}

type Review {
   id: ID!
   postId: ID!
   comment: String!
}

type Query {
    getPost(id: ID!): Post
    getReview(id: ID!): Review
}
```

Várias coisas ocorreram na mesclagem:
+ O tipo `Mutation` não enfrentou conflitos e foi mesclado.
+ Os campos do tipo `Post` foram combinados por meio da operação de união. Observe como a união entre os dois produziu um único `id`, um `title` e um único `reviews`.
+ O tipo `Review` não enfrentou conflitos e foi mesclado.
+ O tipo `Query` não enfrentou conflitos e foi mesclado.

### Gerenciar resolvedores em tipos compartilhados
<a name="resolvers-shared-types-merged-api"></a>

No exemplo acima, considere o caso em que o *Source1.graphql* configurou um resolvedor de unidades em `Query.getPost`, que usa uma fonte de dados do DynamoDB chamada `PostDatasource`. Esse resolvedor retornará o `id` e `title` de um tipo `Post`. Agora, considere que *Source2.graphql* configurou um resolvedor de pipeline em `Post.reviews`, que executa duas funções. `Function1` tem uma fonte de dados `None` anexada para realizar verificações de autorização personalizadas. `Function2` tem uma fonte de dados do DynamoDB anexada para consultar a tabela `reviews`.

```
query GetPostQuery {
    getPost(id: "1") {
        id,
        title,
        reviews
    }
}
```

Quando a consulta acima é executada por um cliente no endpoint da API mesclada, o AWS AppSync serviço primeiro executa o resolvedor de unidades para `Query.getPost` from`Source1`, que chama `PostDatasource` e retorna os dados do DynamoDB. Em seguida, ele executa o resolvedor de pipeline `Post.reviews`, no qual `Function1` executa a lógica de autorização personalizada e `Function2` retorna as avaliações fornecidas ao `id` encontradas em `$context.source`. O serviço processa a solicitação como uma única execução do GraphQL, e essa solicitação simples exigirá apenas um único token de solicitação.

### Gerenciar conflitos de resolvedor em tipos compartilhados
<a name="resolver-conflict-shared-type-merged-api"></a>

Considere o seguinte caso em que também implementamos um resolvedor em `Query.getPost` para fornecer vários campos ao mesmo tempo além do resolvedor de campo em `Source2`. *Source1.graphql* pode parecer da seguinte forma:

```
# This snippet represents a file called Source1.graphql

type Post  {
    id: ID!
    title: String!
    date: AWSDateTime!
}

type Query {
    getPost(id: ID!): Post
}
```

*Source2.graphql* pode parecer da seguinte forma:

```
# This snippet represents a file called Source2.graphql

type Post  {
  id: ID!
  content: String!
  contentHash: String! 
  author: String! 
}

type Query {
    getPost(id: ID!): Post
}
```

A tentativa de mesclar esses dois esquemas gerará um erro de mesclagem porque o AWS AppSync Merged APIs não permite que vários resolvedores de origem sejam anexados ao mesmo campo. Para resolver esse conflito, você pode implementar um padrão de resolvedor de campo que exigiria que o *Source2.graphql* adicionasse um tipo separado que definirá os campos que ele possui do tipo `Post`. No exemplo a seguir, adicionamos um tipo chamado `PostInfo`, que contém os campos de conteúdo e autor que serão resolvidos pelo *Source2.graphql*. O *Source1.graphql* implementará o resolvedor anexado a `Query.getPost`, enquanto o *Source2.graphql* agora anexará um resolvedor a `Post.postInfo` para garantir que todos os dados possam ser recuperados com sucesso:

```
type Post  {
  id: ID!
  postInfo: PostInfo
}

type PostInfo {
   content: String!
   contentHash: String!
   author: String!
}

type Query {
    getPost(id: ID!): Post
}
```

Embora a resolução desse conflito exija que os esquemas da API de origem sejam reescritos e, potencialmente, que os clientes alterem suas consultas, a vantagem dessa abordagem é que a propriedade dos resolvedores mesclados permanece clara entre todas as equipes de origem.

## Configurar esquemas
<a name="configuring-schemas-merged-api"></a>

Duas partes são responsáveis por configurar os esquemas para criar uma API mesclada:
+ **Proprietários da API mesclada** - Os proprietários da API mesclada devem definir a lógica de autorização e as configurações avançadas da API mesclada, como registro em log, rastreamento, armazenamento em cache e suporte ao WAF.
+ **Proprietários da API de origem associada** - Os proprietários da API associada devem configurar os esquemas, os resolvedores e as fontes de dados que compõem a API mesclada.

**Como o esquema da API mesclada é criado a partir dos esquemas da fonte associada APIs, ele é somente para leitura.** Isso significa que as alterações no esquema devem ser iniciadas em sua fonte APIs. **No AWS AppSync console, você pode alternar entre o esquema mesclado e os esquemas individuais da fonte APIs incluídos na API mesclada usando a lista suspensa acima da janela Esquema.**

## Configurar modos de autorização
<a name="configuring-authorization-merged-api"></a>

Vários modos de autorização estão disponíveis para proteger sua API mesclada. Para saber mais sobre os modos de autorização em AWS AppSync, consulte [Autorização e autenticação](https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html).

Os seguintes modos de autorização estão disponíveis para uso com o Merged APIs:
+  **Chave de API**: a estratégia de autorização mais simples. Todas as solicitações devem incluir uma chave de API no cabeçalho da solicitação `x-api-key`. As chaves de API expiradas são mantidas por 60 dias após a data de expiração. 
+  **AWS Identity and Access Management (IAM)****: a estratégia de autorização AWS do IAM autoriza todas as solicitações assinadas com sigv4.** 
+  **Grupos de usuários do Amazon Cognito**: autorize seus usuários por meio dos grupos de usuários do Amazon Cognito para obter um controle mais refinado. 
+  **AWS Autorizadores Lambda**: uma função sem servidor que permite autenticar e autorizar o acesso à sua API usando lógica personalizada. AWS AppSync 
+ **OpenID Connect**: esse tipo de autorização impõe tokens do OpenID Connect (OIDC) fornecidos por um serviço compatível com OIDC. O aplicativo pode aproveitar os usuários e os privilégios definidos pelo provedor de OIDC para controlar o acesso.

Os modos de autorização de uma API mesclada são configurados pelo proprietário da API mesclada. No momento de uma operação de mesclagem, a API mesclada deve incluir o modo de autorização principal configurado em uma API de origem como seu próprio modo de autorização principal ou como um modo de autorização secundário. Caso contrário, ela será incompatível e a operação de mesclagem falhará devido a um conflito. Ao usar diretivas de autenticação múltipla na origem APIs, o processo de mesclagem é capaz de mesclar automaticamente essas diretivas no endpoint unificado. Caso o modo de autorização principal da API de origem não corresponda ao modo de autorização principal da API mesclada, ele adicionará automaticamente essas diretivas de autenticação para garantir que o modo de autorização dos tipos na API de origem seja consistente.

## Configurar perfis de execução
<a name="execution-roles-merged-api"></a>

Ao criar uma API mesclada, você precisa definir um perfil de serviço. Uma função AWS de serviço é uma função de AWS Identity and Access Management (IAM) usada AWS pelos serviços para realizar tarefas em seu nome.

Nesse contexto, é necessário que sua API mesclada execute resolvedores que acessem dados das fontes de dados configuradas em sua fonte. APIs A função de serviço necessária para isso é a`mergedApiExecutionRole`, e ela deve ter acesso explícito para executar solicitações na fonte APIs incluída em sua API mesclada por meio da permissão do `appsync:SourceGraphQL` IAM. Durante a execução de uma solicitação do GraphQL, o AWS AppSync serviço assumirá essa função de serviço e autorizará a função a realizar a ação. `appsync:SourceGraphQL`

AWS AppSync suporta permitir ou negar essa permissão em campos específicos de nível superior dentro da solicitação, como o modo de autorização do IAM funciona para o IAM. APIs Para non-top-level campos, é AWS AppSync necessário definir a permissão no próprio ARN da API de origem. *Para restringir o acesso a non-top-level campos específicos na API mesclada, recomendamos implementar uma lógica personalizada em seu Lambda ou ocultar os campos da API de origem da API mesclada usando a diretiva @hidden.* Se você quiser permitir que o perfil execute todas as operações de dados em uma API de origem, adicione a política abaixo. Observe que a primeira entrada de recurso permite acesso a todos os campos de nível superior e a segunda entrada abrange resolvedores secundários que autorizam o próprio atributo da API de origem: 

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [{
        "Effect": "Allow", 
        "Action": [ "appsync:SourceGraphQL"], 
        "Resource": [ 
            "arn:aws:appsync:us-west-2:123456789012:apis/YourSourceGraphQLApiId/*", 
            "arn:aws:appsync:us-west-2:123456789012:apis/YourSourceGraphQLApiId"] 
    }] 
}
```

------

Se quiser limitar o acesso somente a um campo específico de nível superior, você pode usar uma política como esta:

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [{
        "Effect": "Allow", 
        "Action": [ "appsync:SourceGraphQL"], 
        "Resource": [ 
            "arn:aws:appsync:us-west-2:123456789012:apis/YourSourceGraphQLApiId/types/Query/fields/<Field-1>",
            "arn:aws:appsync:us-west-2:123456789012:apis/YourSourceGraphQLApiId"] 
    }] 
}
```

------

Você também pode usar o assistente de criação de API do AWS AppSync console para gerar uma função de serviço para permitir que sua API mesclada acesse recursos configurados na fonte APIs que estão na mesma conta da sua API mesclada. Caso sua fonte não APIs esteja na mesma conta da API mesclada, você deve primeiro compartilhar seus AWS recursos usando o Resource Access Manager (AWS RAM). 

## Configurando contas cruzadas mescladas usando APIs AWS RAM
<a name="cross-account-merged-api"></a>

Ao criar uma API mesclada, você pode, opcionalmente, associar a fonte APIs de outras contas que foram compartilhadas por meio do AWS Resource Access Manager ()AWS RAM. AWS RAM ajuda você a compartilhar seus recursos com segurança entre AWS contas, dentro de sua organização ou unidades organizacionais (OUs) e com funções e usuários do IAM.

AWS AppSync se integra AWS RAM para oferecer suporte à configuração e ao acesso à fonte APIs em várias contas a partir de uma única API mesclada. AWS RAM permite criar um compartilhamento de recursos ou um contêiner de recursos e os conjuntos de permissões que serão compartilhados para cada um deles. Você pode adicionar AWS AppSync APIs a um compartilhamento de recursos no AWS RAM. Em um compartilhamento de recursos, AWS AppSync fornece três conjuntos de permissões diferentes que podem ser associados a uma AWS AppSync API na RAM:

1. `AWSRAMPermissionAppSyncSourceApiOperationAccess`: o conjunto de permissões padrão que é adicionado ao compartilhar uma AWS AppSync API AWS RAM se nenhuma outra permissão for especificada. Esse conjunto de permissões é usado para compartilhar uma AWS AppSync API de origem com um proprietário da API mesclada. Esse conjunto de permissões inclui a permissão para `appsync:AssociateMergedGraphqlApi` a API de origem, bem como a permissão `appsync:SourceGraphQL` necessária para acessar os atributos da API de origem em runtime.

1. `AWSRAMPermissionAppSyncMergedApiOperationAccess`: esse conjunto de permissões deve ser configurado ao compartilhar uma API mesclada com o proprietário da API de origem. Esse conjunto de permissões dará à API de origem a capacidade de configurar a API mesclada, incluindo a capacidade de associar qualquer fonte APIs pertencente ao principal de destino à API mesclada e de ler e atualizar as associações de API de origem da API mesclada.

1. `AWSRAMPermissionAppSyncAllowSourceGraphQLAccess`: esse conjunto de permissões permite que a `appsync:SourceGraphQL` permissão seja usada com uma AWS AppSync API. Ele deve ser usado para compartilhar uma API de origem com um proprietário da API mesclada. Ao contrário do conjunto de permissões padrão para acesso à operação da API de origem, esse conjunto de permissões inclui apenas a permissão de runtime `appsync:SourceGraphQL`. Se um usuário optar por compartilhar o acesso à operação da API mesclada com um proprietário da API de origem, ele também precisará compartilhar essa permissão da API de origem com o proprietário da API mesclada para ter acesso de runtime por meio do endpoint da API mesclada.

AWS AppSync também oferece suporte a permissões gerenciadas pelo cliente. Quando uma das permissões AWS gerenciadas fornecidas não funciona, você pode criar sua própria permissão gerenciada pelo cliente. As permissões gerenciadas pelo cliente são permissões gerenciadas que você cria e mantém especificando com precisão quais ações podem ser executadas sob quais condições com o uso de recursos compartilhados. AWS RAM AWS AppSync permite que você escolha entre as seguintes ações ao criar sua própria permissão:

1. `appsync:AssociateSourceGraphqlApi`

1. `appsync:AssociateMergedGraphqlApi`

1. `appsync:GetSourceApiAssociation`

1. `appsync:UpdateSourceApiAssociation`

1. `appsync:StartSchemaMerge`

1. `appsync:ListTypesByAssociation`

1. `appsync:SourceGraphQL`

Depois de compartilhar adequadamente uma API de origem ou API mesclada AWS RAM e, se necessário, o convite de compartilhamento de recursos ter sido aceito, ele ficará visível no AWS AppSync console quando você criar ou atualizar as associações da API de origem na sua API mesclada. Você também pode listar tudo o AWS AppSync APIs que foi compartilhado usando AWS RAM sua conta, independentemente da permissão definida, chamando a `ListGraphqlApis` operação fornecida por AWS AppSync e usando o filtro do `OTHER_ACCOUNTS` proprietário. 

**nota**  
O compartilhamento via AWS RAM exige que o chamador tenha permissão para realizar a `appsync:PutResourcePolicy` ação em qualquer API que esteja sendo compartilhada. AWS RAM 

## Mesclar
<a name="merges"></a>

### Gerenciar mesclagens
<a name="managing-merges"></a>

 APIs Os mesclados têm como objetivo apoiar a colaboração da equipe em um AWS AppSync endpoint unificado. As equipes podem desenvolver de forma independente sua própria fonte isolada de APIs GraphQL no back-end, enquanto AWS AppSync o serviço gerencia a integração dos recursos em um único endpoint de API mesclada, a fim de reduzir o atrito na colaboração e diminuir os prazos de desenvolvimento.

### Mesclagens automáticas
<a name="auto-merge"></a>

A fonte APIs associada à sua API AWS AppSync mesclada pode ser configurada para ser mesclada automaticamente (mesclagem automática) na API mesclada após qualquer alteração ser feita na API de origem. Isso garante que as alterações da API de origem sejam sempre propagadas para o endpoint da API mesclada em segundo plano. Qualquer alteração no esquema da API de origem será atualizada na API mesclada, desde que isso não introduza um conflito de mesclagem com uma definição existente na API mesclada. Se a atualização na API de origem for atualizar um resolvedor, fonte de dados ou função, o atributo importado também será atualizado. Quando um novo conflito é introduzido e não pode ser resolvido automaticamente (resolvido automaticamente), a atualização do esquema da API mesclada é rejeitada devido a um conflito não compatível durante a operação de mesclagem. A mensagem de erro está disponível no console para cada associação de API de origem que tenha um status de `MERGE_FAILED`. Você também pode inspecionar a mensagem de erro chamando a `GetSourceApiAssociation` operação de uma determinada associação de API de origem usando o AWS SDK ou usando a AWS CLI da seguinte forma:

```
aws appsync get-source-api-association --merged-api-identifier <Merged API ARN> --association-id <SourceApiAssociation id>
```

Isso produzirá um resultado no seguinte formato:

```
{
    "sourceApiAssociation": {
        "associationId": "<association id>",
        "associationArn": "<association arn>",
        "sourceApiId": "<source api id>",
        "sourceApiArn": "<source api arn>",
        "mergedApiArn": "<merged api arn>",
        "mergedApiId": "<merged api id>",
        "sourceApiAssociationConfig": {
            "mergeType": "MANUAL_MERGE"
        },
        "sourceApiAssociationStatus": "MERGE_FAILED",
        "sourceApiAssociationStatusDetail": "Unable to resolve conflict on object with name title: Merging is not supported for fields with different types."
    }
}
```

### Mesclagens manuais
<a name="manual-merges"></a>

A configuração padrão para uma API de origem é uma mesclagem manual. Para mesclar as alterações que ocorreram na fonte APIs desde a última atualização da API mesclada, o proprietário da API de origem pode invocar uma mesclagem manual a partir do AWS AppSync console ou por meio da `StartSchemaMerge` operação disponível no SDK AWS e na CLI. AWS 

## Suporte adicional para Merged APIs
<a name="merge-api-additional-support"></a>

### Configurar assinaturas
<a name="config-subscription"></a>

Ao contrário das abordagens baseadas em roteador para a composição do esquema do GraphQL, o AWS AppSync Merged fornece suporte APIs integrado para assinaturas do GraphQL. Todas as operações de assinatura definidas em sua fonte associada APIs serão mescladas e funcionarão automaticamente em sua API mesclada sem modificação. [Para saber mais sobre como AWS AppSync oferece suporte a assinaturas por meio de WebSockets conexão sem servidor, consulte Dados em tempo real.](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-data.html)

### Configurar a observabilidade
<a name="config-observability"></a>

AWS AppSync O Merged APIs fornece registro, monitoramento e métricas integrados via [Amazon CloudWatch](https://docs.aws.amazon.com/appsync/latest/devguide/monitoring.html). AWS AppSync também fornece suporte integrado para rastreamento via [AWS X-Ray](https://docs.aws.amazon.com/appsync/latest/devguide/x-ray-tracing.html). 

### Configurar domínios personalizados
<a name="config-custom-domain"></a>

AWS AppSync [O Merged APIs fornece suporte integrado para o uso de domínios personalizados com o GraphQL e os endpoints em tempo real da API Merged.](https://docs.aws.amazon.com/appsync/latest/devguide/custom-domain-name.html) 

### Configurar o cache
<a name="config-caching"></a>

AWS AppSync O Merged APIs fornece suporte integrado para armazenar, opcionalmente, em cache as respostas em nível de solicitação e/ou em nível de resolvedor, bem como compactação de respostas. Para saber mais, consulte [Armazenamento em cache e compactação](https://docs.aws.amazon.com/appsync/latest/devguide/enabling-caching.html). 

### Configurando o privado APIs
<a name="config-private-api"></a>

AWS AppSync [O Merged APIs fornece suporte integrado para Private, APIs que limita o acesso aos endpoints GraphQL e Real-time da API mesclada ao tráfego proveniente de endpoints VPC que você pode configurar.](https://docs.aws.amazon.com/appsync/latest/devguide/using-private-apis.html) 

### Configurar regras de firewall
<a name="config-firewall"></a>

AWS AppSync O Merged APIs fornece suporte integrado para AWS WAF, o que permite que você proteja você APIs definindo [regras de firewall de aplicativos web](https://docs.aws.amazon.com/appsync/latest/devguide/WAF-Integration.html). 

### Configurar logs de auditoria
<a name="config-audit"></a>

AWS AppSync O Merged APIs fornece suporte integrado para AWS CloudTrail, o que permite [configurar e gerenciar registros de auditoria](https://docs.aws.amazon.com/appsync/latest/devguide/cloudtrail-logging.html). 

## Limitações de APIs mescladas
<a name="merged-api-limits"></a>

Ao desenvolver o Merged APIs, observe as seguintes regras:

1. Uma API mesclada não pode ser uma API de origem para outra API mesclada.

1. Uma API de origem não pode ser associada a mais de uma API mesclada.

1. O limite de tamanho padrão para um documento do esquema da API mesclada é de 10 MB.

1. O número padrão de fontes APIs que pode ser associado a uma API mesclada é 10. No entanto, você pode solicitar um aumento de limite se precisar de mais de 10 fontes APIs em sua API mesclada.

## Considerações sobre a API mesclada
<a name="merged-api-considerations"></a>

Ao projetar e implementar o Merged APIs, considere o seguinte:

A fusão de várias fontes APIs em um único endpoint pode aumentar o tamanho e a complexidade do esquema e das consultas do GraphQL. À medida que seu esquema mesclado cresce, as consultas podem precisar passar por vários resolvedores para atender a uma única solicitação, o que pode adicionar latência ao tempo geral da solicitação. Por exemplo, uma consulta que acessa campos de várias fontes APIs pode exigir AWS AppSync a execução de resolvedores de cada API de origem em sequência, com cada resolvedor aumentando o tempo total de resposta.

É altamente recomendável que você teste seu Merged APIs minuciosamente durante o desenvolvimento e sob condições de carga realistas para garantir que ele atenda aos requisitos de sua empresa. Preste atenção específica a:
+ A profundidade e a complexidade do seu esquema mesclado, especialmente consultas que acessam campos em várias fontes. APIs
+ O número de resolvedores que devem ser executados para atender aos padrões de consulta comuns.
+ As características de desempenho de suas fontes de dados e resolvedores sob carga esperada.
+ O impacto da latência da rede ao acessar recursos em várias fontes APIs.

Considere implementar otimizações de desempenho, como armazenamento em cache, agrupamento de solicitações de fontes de dados em lote e design de seus esquemas de API de origem para minimizar o número de execuções de resolvedor necessárias para operações comuns.

## Criando mesclado APIs
<a name="creating-merged-api"></a>

**Para criar uma API mesclada no console**

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

   1. No **Painel**, selecione **Criar API**.

1. Selecione **API mesclada** e, em seguida, **Avançar**.

1. Na página **Especificar detalhes da API**, insira as seguintes informações: 

   1. Em **Detalhes da API**, insira as seguintes informações:

      1. Especifique o **nome da API** da API mesclada. Esse campo é uma forma de rotular sua API do GraphQL para diferenciá-la convenientemente de outros GraphQL. APIs 

      1. Especifique os **detalhes de contato**. Esse campo é opcional e anexa um nome ou grupo à API do GraphQL. Ele não é vinculado ou gerado por outros atributos e funciona da mesma forma que o campo de nome da API. 

   1. Em **Função de serviço**, você deve anexar uma função de execução do IAM à sua API mesclada para que AWS AppSync possa importar e usar seus recursos com segurança em tempo de execução. Você pode escolher **criar e usar uma nova função de serviço**, o que permitirá especificar as políticas e os recursos que AWS AppSync serão usados. Você também pode importar um perfil do IAM existente escolhendo **Usar um perfil de serviço existente** e selecionando um perfil na lista suspensa. 

   1. Em **Configuração da API privada**, é possível ativar os atributos da API privada. Observe que essa opção não pode ser alterada após a criação da API mesclada. Para obter mais informações sobre privacidade APIs, consulte Como [usar o AWS AppSync privado APIs](https://docs.aws.amazon.com/appsync/latest/devguide/using-private-apis.html). 

      Quando terminar, selecione **Avançar**. 

1. Em seguida, você deve adicionar o GraphQL APIs que será usado como base para sua API mesclada. Na APIs página **Selecionar fonte**, insira as seguintes informações: 

   1. Na tabela **APIs da sua AWS conta**, escolha **Adicionar fonte APIs**. Na lista do GraphQL APIs, cada entrada conterá os seguintes dados:

      1. **Nome**: o campo **nome da API** da API do GraphQL. 

      1. **ID da API**: o valor de ID exclusivo da API do GraphQL.

      1. **Modo de autenticação primária**: o modo de autorização padrão para a API do GraphQL. Para obter mais informações sobre os modos de autorização no AWS AppSync, consulte [Autorização e autenticação](https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html). 

      1. **Modo de autenticação adicional**: os modos de autorização secundários que foram configurados na API do GraphQL.

      1. Escolha o APIs que você usará na API mesclada marcando a caixa de seleção ao lado do campo **Nome** da API. Depois, escolha **Adicionar fonte APIs**. O GraphQL selecionado APIs aparecerá na tabela **APIs de suas AWS contas**.

   1. Na tabela **APIs De outras AWS contas**, escolha **Adicionar fonte APIs**. O GraphQL APIs nesta lista vem de outras contas que estão compartilhando seus recursos com a sua por meio de AWS Resource Access Manager ()AWS RAM. O processo para selecionar o GraphQL APIs nesta tabela é o mesmo da seção anterior. Para obter mais informações sobre o compartilhamento de recursos por meio de AWS RAM, consulte [O que é AWS Resource Access Manager?](https://docs.aws.amazon.com/ram/latest/userguide/what-is.html) .

      Quando terminar, selecione **Avançar**.

   1. Adicione seu modo de autenticação principal. Consulte [Autorização e autenticação](https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html) para obter mais informações. Selecione **Avançar**.

   1. Revise suas entradas e selecione **Criar API**.

# Construindo o GraphQL APIs com introspecção do RDS
<a name="rds-introspection"></a>

O utilitário de introspecção do AWS AppSync pode descobrir modelos de tabelas de banco de dados e propor tipos GraphQL. O assistente Create API do AWS AppSync console pode gerar instantaneamente uma API a partir de um banco de dados Aurora MySQL ou PostgreSQL. Ele cria automaticamente tipos e JavaScript resolvedores para ler e gravar dados.

AWS AppSync fornece integração direta com bancos de dados Amazon Aurora por meio da API de dados do Amazon RDS. Em vez de exigir uma conexão persistente com o banco de dados, a API de dados do Amazon RDS oferece um endpoint HTTP seguro que AWS AppSync se conecta para executar SQL instruções. É possível usá-lo para criar uma API de banco de dados relacional para as workloads MySQL e PostgreSQL no Aurora.

A criação de uma API para seu banco de dados relacional AWS AppSync tem várias vantagens:
+ O banco de dados não é diretamente exposto aos clientes, separando o ponto de acesso do próprio banco de dados. 
+ Você pode criar aplicativos APIs personalizados de acordo com as necessidades de diferentes aplicativos, eliminando a necessidade de lógica de negócios personalizada nos front-ends. Isso se alinha com o padrão Backend-For-Frontend (BFF). 
+ A autorização e o controle de acesso podem ser implementados na AWS AppSync camada usando vários modos de autorização para controlar o acesso. Nenhum recurso computacional adicional é necessário para se conectar ao banco de dados, como hospedar um servidor web ou fazer conexões por proxy. 
+ Recursos em tempo real podem ser adicionados por meio de assinaturas, com mutações de dados feitas por meio de envio AppSync automático para clientes conectados. 
+ Os clientes podem se conectar à API via HTTPS usando portas comuns, como 443.

AWS AppSync facilita a criação APIs a partir de bancos de dados relacionais existentes. O utilitário de introspecção pode descobrir modelos por meio de tabelas de banco de dados e propor tipos de GraphQL. O assistente de *API de criação* do console do AWS AppSync pode gerar instantaneamente uma API por meio de um banco de dados Aurora MySQL ou PostgreSQL. Ele cria automaticamente tipos e JavaScript resolvedores para ler e gravar dados. 

AWS AppSync fornece JavaScript utilitários integrados para simplificar a gravação de instruções SQL em resolvedores. Você pode usar os modelos AWS AppSync de `sql` tags para instruções estáticas com valores dinâmicos ou os utilitários do `rds` módulo para criar instruções programaticamente. Consulte as fontes de dados da [referência de funções de resolvedores do RDS](https://docs.aws.amazon.com//appsync/latest/devguide/resolver-reference-rds-js.html) e [módulos integrados](https://docs.aws.amazon.com//appsync/latest/devguide/built-in-modules-js.html#built-in-rds-modules) para obter mais informações. 

## Usar o recurso de introspecção (console)
<a name="using-introspection-console"></a>

Para ver um tutorial detalhado e um guia de introdução, consulte [Tutorial: Aurora PostgreSQL Serverless with Data API](https://docs.aws.amazon.com//appsync/latest/devguide/aurora-serverless-tutorial-js.html). 

O AWS AppSync console permite que você crie uma API AWS AppSync GraphQL a partir do seu banco de dados Aurora existente configurado com a API de dados em apenas alguns minutos. Isso gera rapidamente um esquema operacional com base na configuração do banco de dados. É possível usar a API no estado em que se encontra ou desenvolvê-la para adicionar recursos. 

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

   1. No **Painel**, escolha **Criar API**.

1. **Em **Opções de API**, escolha **GraphQL APIs**, **Comece com um cluster Amazon Aurora** e, em seguida, Avançar.**

   1. Insira um **Nome da API**. Isso será usado como um identificador para a API no console.

   1. Para **obter detalhes de contato**, você pode inserir um ponto de contato para identificar um gerente para a API. Esse é um campo opcional.

   1. Em **Configuração da API privada**, é possível habilitar os atributos da API privada. Uma API privada só pode ser acessada de um endpoint da VPC (VPCE) configurado. Para obter mais informações, consulte [Privado APIs](https://docs.aws.amazon.com//appsync/latest/devguide/using-private-apis.html).

      Não recomendamos habilitar esse atributo para este exemplo. Após analisar suas entradas, selecione **Próximo**.

1. Na página **Banco de dados**, escolha **Selecionar banco de dados**.

   1. É necessário escolher o banco de dados no cluster. A primeira etapa é selecionar a **região** na qual o cluster existe.

   1. Selecione o **Cluster do Aurora** na lista suspensa. Observe que é necessário ter criado e [habilitado](https://docs.aws.amazon.com//AmazonRDS/latest/AuroraUserGuide/data-api.html#data-api.enabling) uma API de dados correspondente antes de usar o recurso.

   1. Depois, é necessário adicionar as credenciais do banco de dados ao serviço. Isso é feito principalmente usando AWS Secrets Manager. Selecione a **região** onde existe o segredo. Para obter mais informações sobre como recuperar informações de segredos, consulte [Find secrets](https://docs.aws.amazon.com//secretsmanager/latest/userguide/manage_search-secret.html) ou [Retrieve secrets](https://docs.aws.amazon.com//secretsmanager/latest/userguide/retrieving-secrets.html).

   1. Adicione o segredo da lista suspensa. Observe que o usuário deve ter [permissões de leitura](https://docs.aws.amazon.com//AmazonRDS/latest/UserGuide/security_iam_id-based-policy-examples.html#security_iam_id-based-policy-examples-console) para o banco de dados.

1. Escolha **Importar**.

   AWS AppSync começará a introspectar seu banco de dados, descobrindo tabelas, colunas, chaves primárias e índices. Ele confere se as tabelas descobertas podem ser compatíveis com uma API do GraphQL. Observe que, para oferecer suporte à criação de novas linhas, as tabelas precisam de uma chave primária, que pode usar várias colunas. AWS AppSync mapeia as colunas da tabela para campos de texto da seguinte forma:     
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/appsync/latest/devguide/rds-introspection.html)

1. Quando a descoberta da tabela for concluída, a seção **Banco de dados** será preenchida com as informações. Na nova seção **Tabelas do banco de dados**, os dados da tabela podem já estar preenchidos e convertidos em um tipo para o esquema. Se você não vê alguns dos dados necessários, pode verificá-los escolhendo **Adicionar tabelas**, clicando nas caixas de seleção desses tipos no modal exibido e escolhendo **Adicionar**. 

   Para remover um tipo da seção **Tabelas do banco de dados**, clique na caixa de seleção ao lado do tipo a ser removido e selecione **Remover**. Os tipos removidos serão colocados no modal **Adicionar tabelas** se quiser adicioná-los novamente mais tarde.

   Observe que AWS AppSync usa os nomes das tabelas como nomes de tipo, mas você pode renomeá-los, por exemplo, alterando o nome de uma tabela plural *movies* para o nome do tipo. *Movie* Para renomear um tipo na seção **Tabelas do banco de dados**, clique na caixa de seleção do tipo a ser renomeado e, depois, clique no ícone de *lápis* na coluna **Nome do tipo**.

   Para visualizar o conteúdo do esquema com base nas seleções, selecione **Visualizar esquema**. Observe que esse esquema não pode estar vazio. Será necessário ter, pelo menos, uma tabela convertida em um tipo. Além disso, esse esquema não pode exceder 1 MB.

   1. Em **Perfil de serviço**, decida se deseja criar um perfil de serviço especificamente para essa importação ou usar um perfil existente.

1. Escolha **Próximo**.

1. Depois, decida se deseja criar uma API somente leitura (somente consultas) ou uma API para leitura e gravação de dados (com consultas e mutações). O último também aceita assinaturas em tempo real acionadas por mutações. 

1. Escolha **Próximo**.

1. Revise as escolhas e, depois, selecione **Criar API**. O AWS AppSync criará a API e anexará resolvedores a consultas e mutações. A API gerada é totalmente funcional e pode ser estendida conforme necessário. 

## Usar o recurso de introspecção (API)
<a name="using-introspection-api"></a>

É possível usar a API de introspecção `StartDataSourceIntrospection` para descobrir modelos no banco de dados de forma programática. Para obter mais detalhes sobre o comando, consulte Usar a API [https://docs.aws.amazon.com//appsync/latest/APIReference/API_StartDataSourceIntrospection.html](https://docs.aws.amazon.com//appsync/latest/APIReference/API_StartDataSourceIntrospection.html). 

Para usar`StartDataSourceIntrospection`, forneça seu cluster Aurora Amazon Resource Name (ARN), nome do banco de dados e ARN secreto. AWS Secrets Manager O comando inicia o processo de introspecção. É possível recuperar os resultados com o comando `GetDataSourceIntrospection`. É possível especificar se o comando deve exibir a string SDL (linguagem de definição de armazenamento) para os modelos descobertos. Ela é útil para gerar uma definição de esquema SDL diretamente pelos modelos descobertos.

 Por exemplo, se você tiver a seguinte declaração de linguagem de definição de dados (DDL) para uma tabela `Todos` simples:

```
create table if not exists public.todos  
(  
id serial constraint todos_pk primary key,  
description text,  
due timestamp,  
"createdAt" timestamp default now()  
);
```

Você deve começar a introspecção com o seguinte:

```
aws appsync start-data-source-introspection \ 
  --rds-data-api-config resourceArn=<cluster-arn>,secretArn=<secret-arn>,databaseName=database
```

Depois, use o comando `GetDataSourceIntrospection` para recuperar o resultado.

```
aws appsync get-data-source-introspection \
  --introspection-id a1234567-8910-abcd-efgh-identifier \
  --include-models-sdl
```

Ele exibirá o resultado a seguir.

```
{
    "introspectionId": "a1234567-8910-abcd-efgh-identifier",
    "introspectionStatus": "SUCCESS",
    "introspectionStatusDetail": null,
    "introspectionResult": {
        "models": [
            {
                "name": "todos",
                "fields": [
                    {
                        "name": "description",
                        "type": {
                            "kind": "Scalar",
                            "name": "String",
                            "type": null,
                            "values": null
                        },
                        "length": 0
                    },
                    {
                        "name": "due",
                        "type": {
                            "kind": "Scalar",
                            "name": "AWSDateTime",
                            "type": null,
                            "values": null
                        },
                        "length": 0
                    },
                    {
                        "name": "id",
                        "type": {
                            "kind": "NonNull",
                            "name": null,
                            "type": {
                                "kind": "Scalar",
                                "name": "Int",
                                "type": null,
                                "values": null
                            },
                            "values": null
                        },
                        "length": 0
                    },
                    {
                        "name": "createdAt",
                        "type": {
                            "kind": "Scalar",
                            "name": "AWSDateTime",
                            "type": null,
                            "values": null
                        },
                        "length": 0
                    }
                ],
                "primaryKey": {
                    "name": "PRIMARY_KEY",
                    "fields": [
                        "id"
                    ]
                },
                "indexes": [],
                "sdl": "type todos\n{\ndescription: String\n\ndue: AWSDateTime\n\nid: Int!\n\ncreatedAt: AW
SDateTime\n}\n"
            }
        ],
        "nextToken": null
    }
}
```