

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

# 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