

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Uso de suscripciones para aplicaciones de datos en tiempo real en AWS AppSync
<a name="aws-appsync-real-time-data"></a>

**importante**  
A partir del 13 de marzo de 2025, podrás crear una PubSub API en tiempo real con la WebSockets tecnología de AWS AppSync Events. Para obtener más información, consulta [Publicar eventos WebSocket en](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) la *Guía para desarrolladores de AWS AppSync eventos*.

AWS AppSyncpermite utilizar las suscripciones para implementar actualizaciones de aplicaciones en tiempo real, notificaciones push, etc. Cuando los clientes invocan las operaciones de suscripción de GraphQL, se establece y mantiene automáticamente una conexión WebSocket segura. AWS AppSync De este modo, las aplicaciones pueden distribuir los datos en tiempo real desde una fuente de datos a los suscriptores y, al mismo tiempo, gestionar AWS AppSync continuamente los requisitos de conexión y escalado de la aplicación. En las siguientes secciones, se mostrará cómo AWS AppSync funcionan las suscripciones.

## Directivas de suscripción del esquema de GraphQL
<a name="graphql-schema-subscription-directives"></a>

Las suscripciones en AWS AppSync se invocan como respuesta a una mutación. Esto significa que puede crear cualquier fuente de datos en tiempo AWS AppSync real especificando una directiva de esquema de GraphQL en una mutación.

Las bibliotecas AWS Amplify cliente gestionan automáticamente la gestión de las conexiones de las suscripciones. Las bibliotecas utilizan pure WebSockets como protocolo de red entre el cliente y el servicio.

**nota**  
Para controlar la autorización en el momento de la conexión a una suscripción, puede utilizar AWS Identity and Access Management (IAM) AWS Lambda, los grupos de identidades de Amazon Cognito o los grupos de usuarios de Amazon Cognito para la autorización a nivel de campo. Para obtener controles de acceso detallados a las suscripciones, puede adjuntar resolutores a sus campos de suscripción y realizar una lógica utilizando la identidad de la persona que llama y las fuentes de datos. AWS AppSync Para obtener más información, consulte [Configuración de la autorización y la autenticación para proteger su GraphQL APIs](security-authz.md).

Las suscripciones se activan a partir de mutaciones y el conjunto de mutaciones seleccionado se envía a los suscriptores.

En el siguiente ejemplo se muestra cómo usar las suscripciones de GraphQL. No especifica una fuente de datos porque la fuente de datos puede ser Lambda, Amazon DynamoDB o Amazon Service. OpenSearch 

Para comenzar a utilizar las suscripciones, debe agregar un punto de entrada de la suscripción a su esquema de este modo:

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

Imagine que dispone de un sitio donde se publican blogs y que desea suscribirse a nuevos blogs y a los cambios en los blogs existentes. Para ello, puede añadir la siguiente definición `Subscription` a su esquema:

```
type Subscription {
    addedPost: Post
    updatedPost: Post
    deletedPost: Post
}
```

Imagine también que tiene las siguientes mutaciones:

```
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!
}
```

Puede convertir estos campos a tiempo real añadiendo una directiva `@aws_subscribe(mutations: ["mutation_field_1", "mutation_field_2"])` para cada una de las suscripciones de las que desea recibir notificaciones, tal y como se indica a continuación:

```
type Subscription {
    addedPost: Post
    @aws_subscribe(mutations: ["addPost"])
    updatedPost: Post
    @aws_subscribe(mutations: ["updatePost"])
    deletedPost: Post
    @aws_subscribe(mutations: ["deletePost"])
}
```

Dado que la mutación `@aws_subscribe(mutations: ["",..,""])` tiene una matriz de entradas de mutaciones, puede especificar varias mutaciones que inician una suscripción. Si se suscribe desde un cliente, su consulta de GraphQL podría tener el siguiente aspecto:

```
subscription NewPostSub {
    addedPost {
        __typename
        version
        title
        content
        author
        url
    }
}
```

Esta consulta de suscripción es necesaria para las conexiones de cliente y para las herramientas.

En el caso del WebSockets cliente puro, el filtrado del conjunto de selecciones se realiza por cliente, ya que cada cliente puede definir su propio conjunto de selecciones. En este caso, el conjunto de selecciones de la suscripción debe ser un subconjunto del conjunto de selecciones de la mutación. Por ejemplo, una suscripción `addedPost{author title}` vinculada a la mutación `addPost(...){id author title url version}` solo recibe el autor y el título de la publicación. No recibe el resto de campos. Sin embargo, si la mutación no incluye el autor en su conjunto de selecciones, el suscriptor obtiene un valor `null` para el campo de autor (o bien un error, en caso de que el campo de autor se defina como obligatorio o no nulo en el esquema).

El conjunto de selección de suscripciones es esencial cuando se utiliza pure WebSockets. Si un campo no está definido explícitamente en la suscripción, AWS AppSync no lo devuelve.

En el ejemplo anterior, las suscripciones no tenía argumentos. Imaginemos que su esquema es similar al siguiente:

```
type Subscription {
    updatedPost(id:ID! author:String): Post
    @aws_subscribe(mutations: ["updatePost"])
}
```

En este caso, el cliente define una suscripción de este modo:

```
subscription UpdatedPostSub {
    updatedPost(id:"XYZ", author:"ABC") {
        title
        content
    }
}
```

El tipo que devuelve el campo `subscription` del esquema debe coincidir con el tipo devuelto para el campo de mutación correspondiente. En el ejemplo anterior, tanto `addPost` como `addedPost` se devolvían con el tipo `Post`.

Para configurar las suscripciones en el cliente, consulte [Creación de una aplicación cliente mediante el cliente de Amplify](building-a-client-app.md).

## Uso de argumentos de suscripción
<a name="using-subscription-arguments"></a>

Un aspecto importante del uso de las suscripciones de GraphQL es comprender cuándo y cómo se deben usar los argumentos. Puede hacer cambios sutiles para modificar la forma y el momento de informar a los clientes acerca de las mutaciones que se han producido. Para ello, consulte el esquema de ejemplo del capítulo de inicio rápido, en el que se crean “Todos”. Para este esquema de ejemplo se definen las mutaciones siguientes:

```
type Mutation {
    createTodo(input: CreateTodoInput!): Todo
    updateTodo(input: UpdateTodoInput!): Todo
    deleteTodo(input: DeleteTodoInput!): Todo
}
```

En el ejemplo de muestra, los clientes pueden suscribirse a las actualizaciones de cualquier `Todo` utilizando la opción `onUpdateTodo` `subscription` sin argumentos:

```
subscription OnUpdateTodo {
  onUpdateTodo {
    description
    id
    name
    when
  }
}
```

Puede filtrar su `subscription` utilizando sus argumentos. Por ejemplo, para activar solo una `subscription` cuando se actualiza un `todo` con un `ID` específico, especifique el valor `ID`:

```
subscription OnUpdateTodo {
  onUpdateTodo(id: "a-todo-id") {
    description
    id
    name
    when
  }
}
```

También se pueden transferir varios argumentos. Por ejemplo, la siguiente `subscription` muestra cómo recibir notificaciones de cualquier actualización de `Todo` en un lugar y hora específicos:

```
subscription todosAtHome {
  onUpdateTodo(when: "tomorrow", where: "at home") {
    description
    id
    name
    when
    where
  }
}
```

Tenga en cuenta que todos los argumentos son opcionales. Si no especifica ningún argumento en su `subscription`, se suscribirá a todas las actualizaciones de `Todo` que se produzcan en su aplicación. Sin embargo, puede actualizar la definición de campo de su `subscription` para requerir el argumento `ID`. De este modo, forzaría la respuesta de un `todo` específico en lugar de la de todos los `todo`:

```
onUpdateTodo(
  id: ID!,
  name: String,
  when: String,
  where: String,
  description: String
): Todo
```

### El valor nulo del argumento tiene un significado
<a name="argument-null-value-has-meaning"></a>

Al realizar una consulta de suscripción AWS AppSync, el valor de un `null` argumento filtrará los resultados de forma diferente a cuando se omita el argumento por completo.

Volvamos al ejemplo de la API de todos, donde podríamos crear todos. Consulte el ejemplo de esquema del capítulo de inicio rápido.

Vamos a modificar nuestro esquema para incluir un nuevo campo `owner`, del tipo `Todo`, que describa quién es el propietario. El campo `owner` no es obligatorio y solo se puede configurar en `UpdateTodoInput`. Consulte la siguiente versión simplificada del 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"])
}
```

La siguiente suscripción devuelve todas las actualizaciones de `Todo`:

```
subscription MySubscription {
  onUpdateTodo {
    description
    id
    name
    when
    where
  }
}
```

Si modifica la suscripción anterior para agregar el argumento del campo `owner: null`, ahora está planteando una pregunta diferente. Ahora, esta suscripción registra al cliente para recibir notificaciones de todas las actualizaciones de `Todo` que no hayan indicado un propietario.

```
subscription MySubscription {
  onUpdateTodo(owner: null) {
    description
    id
    name
    when
    where
  }
}
```

**nota**  
**A partir del 1 de enero de 2022, MQTT over ya no WebSockets está disponible como protocolo para las suscripciones a GraphQL en. AWS AppSync APIs Pure WebSockets es el único protocolo compatible. AWS AppSync**  
Los clientes basados en el AWS AppSync SDK o las bibliotecas Amplify, lanzadas después de noviembre de 2019, utilizan pure automáticamente de forma WebSockets predeterminada. La actualización de los clientes a la última versión les permite utilizar AWS AppSync el WebSockets motor puro.  
 WebSockets Los Pure vienen con un tamaño de carga mayor (240 KB), una variedad más amplia de opciones de cliente y CloudWatch métricas mejoradas. Para obtener más información sobre el uso de WebSocket clientes puros, consulte[Crear un cliente en tiempo real en WebSocket AWS AppSync](real-time-websocket-client.md).

# Creación de genéricos pub/sub APIs con tecnología sin servidor WebSockets en AWS AppSync
<a name="aws-appsync-real-time-create-generic-api-serverless-websocket"></a>

**importante**  
A partir del 13 de marzo de 2025, podrás crear una PubSub API en tiempo real con la WebSockets tecnología de AWS AppSync Events. Para obtener más información, consulta [Publicar eventos WebSocket en](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) la *Guía para desarrolladores de AWS AppSync eventos*.

Algunas aplicaciones solo requieren aplicaciones sencillas, WebSocket APIs donde los clientes escuchan un canal o tema específico. Los datos JSON genéricos sin un formato específico ni requisitos estrictamente definidos se pueden distribuir a los clientes que escuchan algunos de estos canales en un patrón de publicación suscripción (pub/sub) puro y simple.

 AWS AppSync Utilízalo para implementar código GraphQL de forma sencilla y pub/sub WebSocket APIs con poco o ningún conocimiento sobre GraphQL en cuestión de minutos, ya que genera automáticamente código GraphQL tanto en el backend de la API como en el lado del cliente.

## Crea y configura pub-sub APIs
<a name="aws-appsync-real-time-enhanced-filtering-using-pub-sub-apis"></a>

Para empezar, siga estos pasos: 

1. [Inicie sesión en la consola Consola de administración de AWS y ábrala. AppSync ](https://console.aws.amazon.com/appsync/)

   1. En el **Panel**, elija **Crear API**.

1. En la siguiente pantalla, seleccione **Crear una API en tiempo real** y, a continuación, seleccione **Siguiente**.

1. Introduce un nombre descriptivo para tu pub/sub API.

1. Puede habilitar las características de [API privada](https://docs.aws.amazon.com/appsync/latest/devguide/using-private-apis.html), pero le recomendamos que mantenga esta opción desactivada por ahora. Elija **Siguiente**.

1. Puedes optar por generar automáticamente una pub/sub API que funcione utilizando WebSockets. También recomendamos mantener esta característica desactivada por el momento. Elija **Siguiente**.

1. Seleccione **Crear API** y, a continuación, espere un par de minutos. Se creará una nueva API AWS AppSync pub/sub preconfigurada en tu cuenta. AWS 

La API utiliza AWS AppSync los solucionadores locales integrados (para obtener más información sobre el uso de los solucionadores locales, consulte el [tutorial sobre resoluciones locales](https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-local-resolvers-js.html) en la *Guía para AWS AppSync desarrolladores*) para administrar varios pub/sub canales y WebSocket conexiones temporales, lo que entrega y filtra automáticamente los datos a los clientes suscritos basándose únicamente en el nombre del canal. Las llamadas a la API se autorizan con una clave de API.

Una vez implementada la API, verá un par de pasos adicionales para generar el código de cliente e integrarlo con su aplicación cliente. Para ver un ejemplo de cómo integrar rápidamente un cliente, en esta guía se utilizará una sencilla aplicación web de React.

1. Para empezar cree una aplicación de React reutilizable usando [NPM](https://www.npmjs.com/get-npm) en su máquina local:

   ```
   $ npx create-react-app mypubsub-app 
   $ cd mypubsub-app
   ```
**nota**  
En este ejemplo, se utilizan las [bibliotecas Amplify](https://docs.amplify.aws/lib/) para conectar los clientes a la API de backend. Sin embargo, no es necesario crear un proyecto de CLI de Amplify a nivel local. Si bien React es el cliente preferido para este ejemplo, las bibliotecas de Amplify también son compatibles con los clientes de iOS, Android y Flutter, y proporcionan las mismas capacidades en estos tiempos de ejecución diferentes. [Los clientes Amplify compatibles proporcionan abstracciones sencillas para interactuar con los backends de la API de AWS AppSync GraphQL con pocas líneas de código, incluidas WebSocket capacidades integradas totalmente compatibles con el protocolo en tiempo real:AWS AppSync WebSocket ](https://docs.aws.amazon.com/appsync/latest/devguide/real-time-websocket-client.html)  

   ```
   $ npm install @aws-amplify/api
   ```

1. En la AWS AppSync consola, selecciona Descargar y **JavaScript**, a continuación, **Descargar** para descargar un único archivo con los detalles de configuración de la API y el código de operaciones de GraphQL generado.

1. Copie el archivo descargado en la carpeta `/src` de su proyecto de React.

1. A continuación, reemplace el contenido del archivo `src/App.js` reutilizable existente por el código de cliente de muestra disponible en la consola.

1. Utilice el comando siguiente para compilar y ejecutar la aplicación a nivel local:

   ```
   $ npm start
   ```

1. Para probar el envío y la recepción de datos en tiempo real, abre dos ventanas del navegador y accede*localhost:3000*. La aplicación de muestra está configurada para enviar datos JSON genéricos a un canal codificado denominado*robots*.

1.  En una de las ventanas del navegador, introduzca el siguiente blob JSON en el cuadro de texto y, a continuación, haz clic en **Enviar**: 

   ```
   {
     "robot":"r2d2",
     "planet": "tatooine"
   }
   ```

Ambas instancias del navegador están suscritas al *robots* canal y reciben los datos publicados en tiempo real, que se muestran en la parte inferior de la aplicación web:

![\[Ejemplo de aplicación React para API pub/sub\]](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/pub-sub-react.png)


Todo el código de la API GraphQL necesario, incluidos el esquema, los resolutores y las operaciones, se generan automáticamente para permitir un caso de uso genérico pub/sub . En el backend, los datos se publican en el punto final en tiempo real con una mutación de GraphQL como la siguiente: AWS AppSync

```
mutation PublishData {
    publish(data: "{\"msg\": \"hello world!\"}", name: "channel") {
        data
        name
    }
}
```

Los suscriptores acceden a los datos publicados que se envían al canal temporal específico con una suscripción de GraphQL relacionada:

```
subscription SubscribeToData {
    subscribe(name:"channel") {
        name
        data
    }
}
```

## Implementación de pub-sub APIs en aplicaciones existentes
<a name="aws-appsync-real-time-enhanced-filtering-existing-apps"></a>

En caso de que solo necesite implementar una función en tiempo real en una aplicación existente, esta configuración genérica de pub/sub API se puede integrar fácilmente en cualquier aplicación o tecnología de API. Si bien utilizar un único punto final de API para acceder, manipular y combinar de forma segura los datos de una o más fuentes de datos en una sola llamada de red con GraphQL, no es necesario convertir o reconstruir una aplicación existente basada en REST desde cero para aprovechar las capacidades en tiempo real AWS AppSync de GraphQL. Por ejemplo, podrías tener una carga de trabajo CRUD existente en un punto final de API independiente en el que los clientes envíen y reciban mensajes o eventos de la aplicación existente a la pub/sub API genérica solo en tiempo real y pub/sub con fines específicos. 

# Definir filtros de suscripciones mejorados en AWS AppSync
<a name="aws-appsync-real-time-enhanced-filtering"></a>

**importante**  
A partir del 13 de marzo de 2025, podrás crear una PubSub API en tiempo real con la WebSockets tecnología de AWS AppSync Events. Para obtener más información, consulta [Publicar eventos WebSocket en](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) la *Guía para desarrolladores de AWS AppSync eventos*.

En AWS AppSync, puedes definir y habilitar la lógica empresarial para el filtrado de datos en el backend directamente en los solucionadores de suscripciones de la API GraphQL mediante filtros que admitan operadores lógicos adicionales. A diferencia de los argumentos de suscripción que se definen en la consulta de suscripción en el cliente, en este caso sí puede configurar estos filtros. Para obtener más información acerca de los argumentos de suscripción, consulte [Uso de argumentos de suscripción](aws-appsync-real-time-data.md#using-subscription-arguments). Para ver una lista de operadores, consulte [AWS AppSync referencia de la utilidad de plantilla de mapeo de resolución](resolver-util-reference.md).

Para los fines de este documento, dividimos el filtrado de datos en tiempo real en las siguientes categorías:
+ **Filtrado básico**: filtrado basado en los argumentos definidos por el cliente en la consulta de suscripción.
+ **Filtrado mejorado**: filtrado basado en la lógica definida de forma centralizada en el backend del AWS AppSync servicio.

En las siguientes secciones se explica cómo configurar los filtros de suscripción mejorados y se muestran sus aplicaciones prácticas.

## Definición de suscripciones en su esquema de GraphQL
<a name="aws-appsync-real-time-enhanced-filtering-using-subscription-filters"></a>

Para usar filtros de suscripción mejorados, defina la suscripción en el esquema de GraphQL y, a continuación, defina el filtro mejorado mediante una extensión de filtrado. Para ilustrar cómo funciona el filtrado de suscripciones mejorado AWS AppSync, utilice el siguiente esquema de GraphQL, que define la API de un sistema de gestión de tickets, como ejemplo:

```
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
```

Supongamos que crea un origen de datos `NONE` para su API y, a continuación, adjunta un solucionador a la mutación `createTicket` utilizando este origen de datos. Los controladores pueden tener un aspecto similar al siguiente:

```
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**  
Los filtros mejorados están habilitados en el controlador del solucionador de GraphQL en una suscripción determinada. Para obtener más información, consulte [Referencia al solucionador](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html).

Para implementar el comportamiento del filtro mejorado, debe usar la función `extensions.setSubscriptionFilter()` para definir una expresión de filtro evaluada en función de los datos publicados de una mutación de GraphQL que pueda interesar a los clientes suscritos. Para obtener más información acerca de las extensiones de filtrado, consulte [Extensiones](https://docs.aws.amazon.com//appsync/latest/devguide/extensions-js.html).

En la siguiente sección, se explica cómo utilizar extensiones de filtrado para implementar filtros mejorados.

## Creación de filtros de suscripciones mejorados mediante extensiones de filtrado
<a name="aws-appsync-real-time-enhanced-filtering-defining-filters"></a>

Los filtros mejorados están escritos en JSON en el controlador de respuestas de los solucionadores de la suscripción. Los filtros se pueden agrupar en una lista llamada `filterGroup`. Los filtros se definen mediante al menos una regla, cada una con campos, operadores y valores. Definamos un nuevo solucionador para `onSpecialTicketCreated` que configure un filtro mejorado. Puede configurar varias reglas en un filtro, que se evalúan mediante la lógica AND. Por su parte, varios filtros de un grupo de filtros se evalúan mediante la 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;
}
```

Según los filtros definidos en el ejemplo anterior, los tickets importantes se distribuyen automáticamente a los clientes de la API suscritos si se crea un ticket con:
+ nivel de `priority` `high` o `medium`

  AND 
+ nivel de `severity` mayor o igual que `7` (`ge`)

OR 
+ ticket de `classification` con la definición de `Security` 

  AND 
+ asignación de `group` establecida en `admin` o `operators`

![\[Ejemplo que muestra una consulta de filtrado de tickets\]](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/aws-priority-example.png)


Los filtros definidos en el solucionador de suscripciones (filtrado mejorado) tienen prioridad sobre el filtrado basado únicamente en los argumentos de suscripción (filtrado básico). Para obtener más información acerca de los argumentos de suscripción, consulte [Uso de argumentos de suscripción](https://docs.aws.amazon.com//appsync/latest/devguide/aws-appsync-real-time-data.html#using-subscription-arguments).

Si un argumento está definido en el esquema de GraphQL de la suscripción y es obligatorio, el filtrado basado en el argumento en cuestión solo se lleva a cabo si el argumento está definido como una regla en el método `extensions.setSubscriptionFilter()` del solucionador. Sin embargo, si no hay métodos de filtrado de `extensions` en el solucionador de suscripciones, los argumentos definidos en el cliente se utilizan únicamente para el filtrado básico. No puede utilizar el filtrado básico y el filtrado mejorado a la vez.

Puede usar la [variable `context`](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html) de la lógica de extensión del filtro de la suscripción para acceder a la información contextual sobre la solicitud. Por ejemplo, si utiliza autorizadores personalizados de grupos de usuarios de Amazon Cognito, OIDC o Lambda para la autorización, puede recuperar información sobre sus usuarios en `context.identity` cuando se establezca la suscripción. Puede usar esa información para establecer filtros basados en la identidad de sus usuarios.

Supongamos ahora que desea implementar el comportamiento de filtro mejorado para `onGroupTicketCreated`. La suscripción `onGroupTicketCreated` requiere un nombre `group` obligatorio como argumento. Cuando se crean, a los tickets se les asigna automáticamente un estado `pending`. Puedes configurar un filtro de suscripción para recibir solo los tickets recién creados que pertenezcan al grupo proporcionado:

```
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;
}
```

Cuando los datos se publican mediante una mutación, como en el siguiente ejemplo:

```
mutation CreateTicket {
  createTicket(input: {priority: medium, severity: 2, group: "aws"}) {
    id
    priority
    severity
    status
    group
    createdAt
  }
}
```

Los clientes suscritos esperan que los datos se envíen automáticamente tan pronto WebSockets como se cree un ticket con la `createTicket` mutación:

```
subscription OnGroup {
  onGroupTicketCreated(group: "aws") {
    category
    status
    severity
    priority
    id
    group
    createdAt
    content
  }
}
```

Los clientes se pueden suscribir sin argumentos porque la lógica de filtrado está implementada en el AWS AppSync servicio con un filtrado mejorado, lo que simplifica el código del cliente. Los clientes reciben datos solo si se cumplen los criterios de filtro definidos.

## Definición de filtros mejorados para campos de esquema anidados
<a name="aws-appsync-real-time-enhanced-filters-nested-schema-fields.title"></a>

Puede utilizar el filtrado de suscripciones mejorado para filtrar los campos de esquema anidados. Supongamos que modificamos el esquema de la sección anterior para incluir los tipos de ubicación y dirección:

```
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
```

Con este esquema, puede usar un separador `.` para representar el anidamiento. En el siguiente ejemplo, se agrega una regla de filtrado para un campo de esquema anidado en `location.address.country`. La suscripción se activará si la dirección del ticket se define 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;
}
```

En el ejemplo anterior, `location` representa el nivel de anidamiento uno, `address` representa el nivel de anidamiento dos y `country` representa el nivel de anidamiento tres, todos los cuales están separados por el separador `.`.

Puede probar esta suscripción mediante la mutación `createTicket`:

```
mutation CreateTicketInUSA {
  createTicket(input: {location: "{\"address\":{\"country\":\"USA\"}}"}) {
    category
    content
    createdAt
    group
    id
    location {
      address {
        country
      }
    }
    priority
    severity
    status
  }
}
```

## Definición de filtros mejorados desde el cliente
<a name="aws-appsync-real-time-enhanced-filtering-defining-from-client"></a>

Puede usar el filtrado básico en GraphQL con [argumentos de suscripciones](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-data.html#using-subscription-arguments). El cliente que realiza la llamada en la consulta de suscripción define los valores de los argumentos. Cuando los filtros mejorados están habilitados en una resolución de AWS AppSync suscripciones con el `extensions` filtrado, los filtros secundarios definidos en la resolución tienen prioridad y prioridad.

Configure filtros mejorados dinámicos definidos por el cliente en la suscripción usando un argumento `filter`. Al configurar estos filtros, debe actualizar el esquema de GraphQL para que refleje el nuevo argumento:

```
...
type Subscription {
    onSpecialTicketCreated(filter: String): Ticket
        @aws_subscribe(mutations: ["createTicket"])
}
...
```

A continuación, el cliente puede enviar una consulta de suscripción como en el siguiente ejemplo:

```
subscription onSpecialTicketCreated($filter: String) {
     onSpecialTicketCreated(filter: $filter) {
        id
        group
        description
        priority
        severity
     }
 }
```

Puede configurar la variable de consulta de la siguiente manera:

```
{"filter" : "{\"severity\":{\"le\":2}}"}
```

La utilidad de solucionador `util.transform.toSubscriptionFilter()` se puede implementar en la plantilla de mapeo de respuestas de suscripción para aplicar el filtro definido en el argumento de suscripción a 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;
}
```

Con esta estrategia, los clientes pueden definir sus propios filtros que utilizan una lógica de filtrado mejorada y operadores adicionales. Los filtros se asignan cuando un cliente determinado invoca la consulta de suscripción en una conexión segura. WebSocket Para obtener más información sobre la utilidad de transformación para mejorar el filtrado, incluido el formato de la carga útil de la variable de `filter` consulta, consulte la descripción general de los [JavaScriptresolutores](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html).

## Restricciones adicionales al filtrado mejorado
<a name="aws-appsync-real-time-enhanced-filtering-additional-restrictions"></a>

A continuación, se muestran varios casos de uso en los que se imponen restricciones adicionales a los filtros mejorados:
+ Los filtros mejorados no admiten el filtrado de las listas de objetos de nivel superior. En este caso de uso, los datos publicados de la mutación se ignoran en las suscripciones mejoradas.
+ AWS AppSync admite hasta cinco niveles de anidación. Los filtros más allá del nivel cinco de los campos de esquema de anidamiento se ignoran. Observe la respuesta de GraphQL que aparece a continuación. El campo `continent` en `venue.address.country.metadata.continent` está permitido porque es un nido de nivel cinco. Sin embargo, `financial` en `venue.address.country.metadata.capital.financial` es un nido de nivel seis, por lo que el filtro no funcionará:

  ```
  {
      "data": {
          "onCreateFilterEvent": {
              "venue": {
                  "address": {
                      "country": {
                          "metadata": {
                              "capital": {
                                  "financial": "New York"
                              },
                              "continent" : "North America"
                          }
                      },
                      "state": "WA"
                  },
                  "builtYear": 2023
              },
              "private": false,
          }
      }
  }
  ```

# Cancelar la suscripción de WebSocket las conexiones mediante filtros en AWS AppSync
<a name="aws-appsync-real-time-invalidation"></a>

**importante**  
A partir del 13 de marzo de 2025, podrás crear una PubSub API en tiempo real con la WebSockets tecnología AWS AppSync de Events. Para obtener más información, consulta [Publicar eventos WebSocket en](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) la *Guía para desarrolladores de AWS AppSync eventos*.

En AWS AppSync, puedes cancelar la suscripción por la fuerza y cerrar (invalidar) una WebSocket conexión desde un cliente conectado en función de una lógica de filtrado específica. Esto resulta útil en contextos de autorización, por ejemplo, cuando se elimina un usuario de un grupo.

La invalidación de la suscripción se produce en respuesta a una carga útil definida en una mutación. Le recomendamos que considere las mutaciones utilizadas para invalidar las conexiones a una suscripción como operaciones administrativas de su API y que ajuste el ámbito de los permisos en consecuencia limitando su uso a un usuario administrador, un grupo o un servicio de backend. Por ejemplo, si utiliza directivas de autorización de esquemas como `@aws_auth(cognito_groups: ["Administrators"])` o `@aws_iam`. Para obtener más información, consulte [Uso de modos de autorización adicionales](https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html#using-additional-authorization-modes).

Los filtros de invalidación utilizan la misma sintaxis y lógica que los [filtros de suscripción mejorados](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-enhanced-filtering.html). Defina estos filtros mediante las siguientes utilidades:
+ `extensions.invalidateSubscriptions()`: definido en el controlador de respuestas del solucionador de GraphQL para una mutación.
+ `extensions.setSubscriptionInvalidationFilter()`: definido en el controlador de respuestas del solucionador de GraphQL de las suscripciones vinculadas a la mutación.

[Para obtener más información sobre las extensiones de filtrado por invalidación, consulta la descripción general de los resolutores. JavaScript](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)

## Uso de la invalidación de suscripciones
<a name="aws-appsync-real-time-invalidation-using-invalidations"></a>

Para ver cómo funciona la invalidación de suscripciones AWS AppSync, usa el siguiente esquema de 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 un filtro de invalidación en el código del solucionador de mutaciones `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 };
}
```

Cuando se invoca la mutación, los datos definidos en el objeto `payload` se utilizan para cancelar la suscripción definida en `subscriptionField`. También se define un filtro de invalidación en la plantilla de mapeo de respuestas de la suscripción `onGroupMessageCreated`. 

Si la `extensions.invalidateSubscriptions()` carga útil contiene un ID que coincide con el IDs del cliente suscrito, tal como se define en el filtro, se cancela la suscripción correspondiente. Además, la conexión está cerrada. WebSocket Defina el código del solucionador de suscripciones para la suscripción `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;
}
```

Tenga en cuenta que el controlador de respuestas de suscripción puede tener definidos filtros de suscripción y filtros de invalidación al mismo tiempo.

Por ejemplo, supongamos que el cliente A suscribe a un nuevo usuario con el ID `user-1` en el grupo con el ID `group-1` mediante la siguiente solicitud de suscripción:

```
onGroupMessageCreated(userId : "user-1", groupId: :"group-1"){...}
```

AWS AppSync ejecuta el solucionador de suscripciones, que genera filtros de suscripción e invalidación tal como se definió en la plantilla de mapeo de `onGroupMessageCreated` respuestas anterior. Para el cliente A, los filtros de suscripción solo permiten enviar datos a `group-1`, y los filtros de invalidación están definidos tanto para `user-1` como para `group-1`.

Ahora, supongamos que el cliente B suscribe a un usuario con el ID `user-2` en el grupo con el ID `group-2` mediante la siguiente solicitud de suscripción:

```
onGroupMessageCreated(userId : "user-2", groupId: :"group-2"){...}
```

AWS AppSync ejecuta el solucionador de suscripciones, que genera filtros de suscripción e invalidación. Para el cliente B, los filtros de suscripción solo permiten enviar datos a `group-2`, y los filtros de invalidación están definidos tanto para `user-2` como para `group-2`.

A continuación, supongamos que se crea un nuevo mensaje de grupo con el ID `message-1` mediante una solicitud de mutación, como en el ejemplo siguiente:

```
createGroupMessage(id: "message-1", groupId :
      "group-1", message: "test message"){...}
```

Los clientes suscritos que coincidan con los filtros definidos reciben automáticamente la siguiente carga útil de datos a través de: WebSockets

```
{
  "data": {
    "onGroupMessageCreated": {
      "id": "message-1",
      "groupId": "group-1",
      "message": "test message",
    }
  }
}
```

El cliente A recibe el mensaje porque los criterios de filtrado coinciden con el filtro de suscripción definido. Sin embargo, el cliente B no recibe el mensaje porque el usuario no forma pertenece a `group-1`. Además, la solicitud no coincide con el filtro de suscripción definido en el solucionador de suscripciones.

Por último, supongamos que `user-1` se ha eliminado de `group-1` con la siguiente solicitud de mutación:

```
removeUserFromGroup(userId: "user-1", groupId : "group-1"){...}
```

La mutación provoca la invalidación de la suscripción, tal y como se define en el código del controlador de respuestas del `extensions.invalidateSubscriptions()` solucionador. AWS AppSync a continuación, cancela la suscripción del cliente A y cierra su conexión. WebSocket El cliente B no se ve afectado, ya que la carga de invalidación definida en la mutación no coincide con su usuario o grupo.

Cuando se AWS AppSync invalida una conexión, el cliente recibe un mensaje confirmando que se ha dado de baja:

```
{
  "message": "Subscription complete."
}
```

## Uso de variables de contexto en los filtros de invalidación de suscripciones
<a name="aws-appsync-real-time-invalidation-context"></a>

Al igual que con los filtros de suscripción mejorados, puede utilizar la [variable `context`](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html) de la extensión del filtro de invalidación de suscripciones para acceder a determinados datos.

Por ejemplo, puede configurar una dirección de correo electrónico como carga útil de invalidación en la mutación y, a continuación, vincularle una correspondencia con el atributo de correo electrónico o la solicitud de un usuario suscrito autorizado con los grupos de usuarios de Amazon Cognito o con OpenID Connect. El filtro de invalidación definido en el invalidador de suscripciones `extensions.setSubscriptionInvalidationFilter()` comprueba si la dirección de correo electrónico establecida por la carga útil `extensions.invalidateSubscriptions()` de la mutación coincide con la dirección de correo electrónico recuperada del token JWT del usuario en `context.identity.claims.email`, iniciándose así la invalidación.

# Crear un cliente en tiempo real en WebSocket AWS AppSync
<a name="real-time-websocket-client"></a>

**importante**  
A partir del 13 de marzo de 2025, podrás crear una PubSub API en tiempo real con la WebSockets tecnología de AWS AppSync Events. Para obtener más información, consulta [Publicar eventos WebSocket en](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) la *Guía para desarrolladores de AWS AppSync eventos*.

AWS AppSyncEl WebSocket cliente en tiempo real permite las suscripciones a GraphQL mediante un proceso de varios pasos. El cliente primero establece una WebSocket conexión con el punto final AWS AppSync en tiempo real, envía un mensaje de inicialización de la conexión y espera el reconocimiento. Tras una conexión correcta, el cliente registra las suscripciones enviando mensajes de inicio con consultas únicas IDs y de GraphQL. AWS AppSync confirma que las suscripciones se han realizado correctamente con mensajes de confirmación. A continuación, el cliente escucha los eventos de suscripción, que se activan con las mutaciones correspondientes. Para mantener la conexión, AWS AppSync envía mensajes de mantenimiento periódicos. Al finalizar, el cliente cancela el registro de las suscripciones mediante el envío de mensajes de suspensión. Este sistema admite varias suscripciones en una sola WebSocket conexión y admite varios modos de autorización, incluidas las claves de API, los grupos de usuarios de Amazon Cognito, IAM y Lambda.

## Implementación de WebSocket clientes en tiempo real para suscripciones a GraphQL
<a name="appsynclong-real-time-websocket-client-implementation-guide-for-graphql-subscriptions"></a>

El siguiente diagrama de secuencia y los pasos siguientes muestran el flujo de trabajo de suscripciones en tiempo real entre el WebSocket cliente, el cliente HTTP y AWS AppSync.

![\[Sequence diagram showing WebSocket client, AppSync endpoints, and HTTP client interactions for real-time subscriptions.\]](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/realtime-client-flow.png)


1. El cliente establece una WebSocket conexión con el punto final AWS AppSync en tiempo real. Si hay un error de red, el cliente debe hacer un retardo exponencial con fluctuaciones. Para obtener más información, consulte [Retroceso y fluctuación exponenciales](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/) en el AWS blog de arquitectura.

1. (Opcional) Tras establecer correctamente la WebSocket conexión, el cliente envía un mensaje. `connection_init`

1. Si `connection_init` se envía, el cliente espera un `connection_ack` mensaje de AWS AppSync. Este mensaje incluye un parámetro `connectionTimeoutMs`, que es el tiempo de espera máximo en milisegundos para un mensaje `"ka"` (keep-alive).

1. AWS AppSync envía `"ka"` mensajes periódicamente. El cliente realiza un seguimiento de la hora en que recibió cada mensaje `"ka"`. Si el cliente no recibe un mensaje `"ka"` en cuestión de milisegundos `connectionTimeoutMs`, debe cerrar la conexión.

1. El cliente registra la suscripción enviando un mensaje de suscripción `start`. Una sola WebSocket conexión admite múltiples suscripciones, incluso si están en modos de autorización diferentes.

1. El cliente espera a que se envíen `start_ack` mensajes AWS AppSync para confirmar que las suscripciones se han realizado correctamente. Si hay un error, AWS AppSync devuelve un `"type": "error"` mensaje.

1. El cliente escucha los eventos de suscripción, que se envían después de llamar a la mutación correspondiente. Las consultas y las mutaciones suelen enviarse `https://` al punto final de AWS AppSync GraphQL. Las suscripciones fluyen a través del punto final AWS AppSync en tiempo real mediante secure WebSocket (`wss://`).

1. El cliente anula el registro de la suscripción enviando un mensaje de suscripción `stop`.

1. Tras anular el registro de todas las suscripciones y comprobar que no se están transfiriendo mensajes a través del WebSocket, el cliente puede desconectarse de la WebSocket conexión.

## Detalles del apretón de manos para establecer la conexión WebSocket
<a name="handshake-details-to-establish-the-websocket-connection"></a>

Para conectarse e iniciar un apretón de manos exitoso AWS AppSync, el WebSocket cliente necesita lo siguiente:
+ El punto final AWS AppSync en tiempo real
+ Encabezados: contienen información relevante sobre el AWS AppSync punto final y la autorización. AWS AppSync admite los tres métodos siguientes para proporcionar encabezados: 
  + Encabezados mediante cadena de consulta
    + La información del encabezado está codificada en forma de cadena base64 a partir de un objeto JSON encadenado. Este objeto JSON contiene detalles relacionados con el AWS AppSync punto final y la autorización. El contenido del objeto JSON varía en función del modo de autorización.
  + Encabezados mediante `Sec-WebSocket-Protocol`
    + Una cadena codificada en una URL en base64 del objeto JSON en cadena que contiene información relevante sobre el AWS AppSync punto final y la autorización se transmite como protocolo en el encabezado. `Sec-WebSocket-Protocol` El contenido del objeto JSON varía en función del modo de autorización.
  + Encabezados mediante encabezados HTTP estándar:
    + Los encabezados se pueden pasar como encabezados HTTP estándar en la solicitud de conexión, de forma similar a como se pasan los encabezados para las consultas y mutaciones de GraphQL. AWS AppSync Sin embargo, no es posible pasar encabezados a través de encabezados HTTP estándar en las solicitudes de conexión de API privadas.
+  `payload`: cadena codificada en Base64 de `payload`. La carga útil solo es necesaria si los encabezados se proporcionan mediante una cadena de consulta.

Con estos requisitos, un WebSocket cliente puede conectarse a la URL, que contiene el punto final en tiempo real con la cadena de consulta, utilizando `graphql-ws` como protocolo. WebSocket 

### Descubrir el punto de enlace de en tiempo real desde el punto de enlace de GraphQL
<a name="discovering-the-appsync-real-time-endpoint-from-the-appsync-graphql-endpoint"></a>

El punto final de AWS AppSync GraphQL y el punto final AWS AppSync en tiempo real son ligeramente diferentes en protocolo y dominio. Puedes recuperar el punto final de GraphQL mediante el comando AWS Command Line Interface (AWS CLI). `aws appsync get-graphql-api`

****AWS AppSync Punto final de GraphQL:****  
 `https://example1234567890000.appsync-api.us-east-1.amazonaws.com/graphql`

****AWS AppSync punto final en tiempo real:****  
 `wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql`

Las aplicaciones pueden conectarse al punto final de AWS AppSync GraphQL (`https://`) mediante cualquier cliente HTTP para consultas y mutaciones. Las aplicaciones se pueden conectar al punto final AWS AppSync en tiempo real (`wss://`) mediante cualquier WebSocket cliente para las suscripciones.

Con los nombres de dominio personalizados, puede interactuar con ambos puntos de conexión mediante un único dominio. Por ejemplo, si lo configuras `api.example.com` como tu dominio personalizado, puedes interactuar con tus puntos de conexión GraphQL y en tiempo real de la siguiente manera: URLs

**AWS AppSync punto final GraphQL de dominio personalizado:**  
`https://api.example.com/graphql`

**AWS AppSync punto final en tiempo real de dominio personalizado:**  
`wss://api.example.com/graphql/realtime`

## Formato de parámetros de encabezado basado en el modo AWS AppSync de autorización de la API
<a name="header-parameter-format-based-on-appsync-api-authorization-mode"></a>

El formato del `header` objeto utilizado en la cadena de consulta de conexión varía en función del modo de autorización de la AWS AppSync API. El `host` campo del objeto hace referencia al punto final de AWS AppSync GraphQL, que se utiliza para validar la conexión incluso si la `wss://` llamada se realiza en el punto final en tiempo real. Para iniciar el protocolo de enlace y establecer la conexión autorizada, `payload` debe ser un objeto JSON vacío. La carga útil solo es necesaria si los encabezados se pasan a través de una cadena de consulta.

En las siguientes secciones se muestran los formatos de encabezado para cada modo de autorización.

### Clave de API
<a name="api-key"></a>

#### Encabezado de clave API
<a name="api-key-list"></a>

**Contenido del encabezado**
+  `"host": <string>`: el host del punto final de AWS AppSync GraphQL o tu nombre de dominio personalizado.
+  `"x-api-key": <string>`: la clave de API configurada para la AWS AppSync API.

**Ejemplo**

```
{
    "host":"example1234567890000.appsync-api.us-east-1.amazonaws.com",
    "x-api-key":"da2-12345678901234567890123456"
}
```

**Encabezados mediante cadena de consulta**

En primer lugar, un objeto JSON que contiene el `host` y la `x-api-key` se convierte en una cadena. A continuación, esta cadena se codifica mediante la codificación base64. La cadena codificada en base64 resultante se agrega como un parámetro de consulta con el nombre `header` de la WebSocket URL para establecer la conexión con el AWS AppSync punto final en tiempo real. La URL de solicitud resultante tiene el siguiente formato:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql?header=eyJob3N0IjoiZXhhbXBsZTEyMzQ1Njc4OTAwMDAuYXBwc3luYy1hcGkudXMtZWFzdC0xLmFtYXpvbmF3cy5jb20iLCJ4LWFtei1kYXRlIjoiMjAyMDA0MDFUMDAxMDEwWiIsIngtYXBpLWtleSI6ImRhMi16NHc0NHZoczV6Z2MzZHRqNXNranJsbGxqaSJ9&payload=e30=
```

Es importante tener en cuenta que, además del objeto de encabezado codificado en base64, un objeto JSON vacío \$1\$1 también está codificado en base64 y se incluye como un parámetro de consulta independiente denominado en la URL. `payload` WebSocket

**Encabezados mediante `Sec-WebSocket-Protocol`**

Un objeto JSON que contiene el `host` y la `x-api-key` se convierte en una cadena y, a continuación, se codifica mediante la codificación base64Url. La cadena codificada en base64Url resultante lleva el prefijo `header-`. Esta cadena con prefijo se utiliza luego como un nuevo subprotocolo, además de en el `Sec-WebSocket-Protocol` encabezado, al establecer la conexión con el `graphql-ws` punto final en tiempo real. WebSocket AWS AppSync 

La URL de solicitud resultante tiene el siguiente formato:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

El encabezado `Sec-WebSocket-Protocol` contiene el siguiente valor:

```
"sec-websocket-protocol" : ["graphql-ws", "header-ewogICAgImhvc3QiOiJleGFtcGxlMTIzNDU2Nzg5MDAwMC5hcHBzeW5jLWFwaS51cy1lYXN0LTEuYW1hem9uYXdzLmNvbSIsCiAgICAieC1hcGkta2V5IjoiZGEyLTEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Igp9"]
```

**Encabezados mediante encabezados HTTP estándar**

En este método, la información clave del host y de la API se transmite mediante encabezados HTTP estándar al establecer la WebSocket conexión con el AWS AppSync punto final en tiempo real. La URL de solicitud resultante tiene el siguiente formato:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

Los encabezados de solicitud incluirían lo siguiente:

```
"sec-websocket-protocol" : ["graphql-ws"]
"host":"example1234567890000.appsync-api.us-east-1.amazonaws.com",
"x-api-key":"da2-12345678901234567890123456"
```

### Grupos de usuarios de Amazon Cognito y OpenID Connect (OIDC)
<a name="amazon-cognito-user-pools-and-openid-connect-oidc"></a>

#### Amazon Cognito y encabezado OIDC
<a name="amazon-cognito-user-pools-and-openid-connect-oidc-list"></a>

Contenido del encabezado:
+  `"Authorization": <string>`: un token de ID de JWT. El encabezado puede usar un [esquema Bearer](https://datatracker.ietf.org/doc/html/rfc6750#section-2.1).
+  `"host": <string>`: el host del punto final de AWS AppSync GraphQL o tu nombre de dominio personalizado.

Ejemplo:

```
{
    "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"
}
```

**Encabezados mediante cadena de consulta**

En primer lugar, un objeto JSON que contiene el `host` y la `Authorization` se convierte en una cadena. A continuación, esta cadena se codifica mediante la codificación base64. La cadena codificada en base64 resultante se agrega como un parámetro de consulta con el nombre de la WebSocket URL `header` para establecer la conexión con el punto final en tiempo real. AWS AppSync La URL de solicitud resultante tiene el siguiente formato:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql?header=eyJBdXRob3JpemF0aW9uIjoiZXlKcmFXUWlPaUpqYkc1eGIzQTVlVzVNSzA5UVlYSXJNVEpIV0VGTFNYQmllVTVXTkhoc1FqaFBWVzlZTW5NMldsZHZQU0lzSW1Gc1p5STZJbEpUTWpVMkluMC5leUp6ZFdJaU9pSmhObU5tTWpjd055MHhOamd4TFRRMU5ESXRPV1l4T0MxbE5qWTBNVGcyTmpsa016WWlMQ0psZG1WdWRGOXBaQ0k2SW1Wa016TTVNbU5rTFdOallUTXROR00yT0MxaE5EWXlMVEpsWkdJM1pUTm1ZMkZqWmlJc0luUnZhMlZ1WDNWelpTSTZJbUZqWTJWemN5SXNJbk5qYjNCbElqb2lZWGR6TG1OdloyNXBkRzh1YzJsbmJtbHVMblZ6WlhJdVlXUnRhVzRpTENKaGRYUm9YM1JwYldVaU9qRTFOamswTlRjM01UZ3NJbWx6Y3lJNkltaDBkSEJ6T2x3dlhDOWpiMmR1YVhSdkxXbGtjQzVoY0MxemIzVjBhR1ZoYzNRdE1pNWhiV0Y2YjI1aGQzTXVZMjl0WEM5aGNDMXpiM1YwYUdWaGMzUXRNbDgzT0hZMFNWWmliVkFpTENKbGVIQWlPakUxTmprME5qRXpNakFzSW1saGRDSTZNVFUyT1RRMU56Y3lNQ3dpYW5ScElqb2lOVGd6WmpobVltTXRNemsyTVMwMFl6QTRMV0poWlRBdFl6UXlZMkl4TVRNNU5EWTVJaXdpWTJ4cFpXNTBYMmxrSWpvaU0zRmxhalZsTVhabU16ZDFOM1JvWld3MGRHOTFkREprTVd3aUxDSjFjMlZ5Ym1GdFpTSTZJbVZzYjNKNllXWmxJbjAuQjRjZEp0aDNLRk5wSjZpa1ZwN2U2RFJlZTk1VjZRaS16RUUyREpIN3NIT2wyenhZaTdmLVNtRUdvaDJBRDhlbXhRUllhakJ5ei1yRTRKaDBRT3ltTjJZcy1aSWtNcFZCVFBndS1UTVdEeU9IaERVbVVqMk9QODJ5ZVozd2xaQXRyX2dNNEx6alhVWG1JX0syeUdqdVhmWFRhYTFtdlFFQkcwbVFmVmQ3U2Z3WEItamN2NFJZVmk2ajI1cWdvdzlFdzUydWZ1clBxYUstM1dBS0czMktwVjhKNC1XZWpxOHQwYy15QTdzYjhFbkI1NTFiN1RVOTN1S1JpVlZLM0U1NU5rNUFEUG9hbV9XWUU0NWkzczVxVkFQXy1Jblc3NU5Vb09DR1RzUzhZV01mYjZlY0hZSi0xai1iekEyN3phVDlWamN0WG45YnlORlptS0xwQTJMY3h3IiwiaG9zdCI6ImV4YW1wbGUxMjM0NTY3ODkwMDAwLmFwcHN5bmMtYXBpLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tIn0=&payload=e30=
```

Es importante tener en cuenta que, además del objeto de encabezado codificado en base64, un objeto JSON vacío \$1\$1 también está codificado en base64 y se incluye como un parámetro de consulta independiente denominado en la URL. `payload` WebSocket

**Encabezados mediante `Sec-WebSocket-Protocol`**

Un objeto JSON que contiene el `host` y la `Authorization` se convierte en una cadena y, a continuación, se codifica mediante la codificación base64Url. La cadena codificada en base64Url resultante lleva el prefijo `header-`. Esta cadena con prefijo se utiliza luego como un nuevo subprotocolo, además de en el `Sec-WebSocket-Protocol` encabezado, al establecer la conexión con el `graphql-ws` punto final en tiempo real. WebSocket AWS AppSync 

La URL de solicitud resultante tiene el siguiente formato:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

El encabezado `Sec-WebSocket-Protocol` contiene el siguiente valor:

```
"sec-websocket-protocol" : ["graphql-ws", "header-ewogICAgImhvc3QiOiJleGFtcGxlMTIzNDU2Nzg5MDAwMC5hcHBzeW5jLWFwaS51cy1lYXN0LTEuYW1hem9uYXdzLmNvbSIsCiAgICAieC1hcGkta2V5IjoiZGEyLTEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Igp9"]
```

**Encabezados mediante encabezados HTTP estándar**

En este método, la información del host y de la autorización se transmite mediante encabezados HTTP estándar al establecer la WebSocket conexión con el AWS AppSync punto final en tiempo real. La URL de solicitud resultante tiene el siguiente formato:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

Los encabezados de solicitud incluirían lo siguiente:

```
"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>

#### Encabezado de IAM
<a name="iam-list"></a>

**Contenido del encabezado**
+  `"accept": "application/json, text/javascript"`: un parámetro `<string>` constante.
+  `"content-encoding": "amz-1.0"`: un parámetro `<string>` constante.
+  `"content-type": "application/json; charset=UTF-8"`: un parámetro `<string>` constante.
+  `"host": <string>`: Este es el host del punto final de AWS AppSync GraphQL.
  + `"x-amz-date": <string>`: la marca de tiempo debe estar en UTC y en el formato ISO 8601 siguiente: AAAAMMDD'T'HHMMSS'Z'. Por ejemplo, 20150830T123600Z es una marca de tiempo válida. No incluya milisegundos en la marca de tiempo. Para obtener más información, consulte [Control de fechas en Signature Version 4](https://docs.aws.amazon.com/general/latest/gr/sigv4-date-handling.html) en la *Referencia general de AWS*.
  +  `"X-Amz-Security-Token": <string>`: El token de AWS sesión, que se requiere cuando se utilizan credenciales de seguridad temporales. Para obtener más información, consulte [Uso de credenciales temporales con  AWS](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_credentials_temp_use-resources.html) en la *Guía del usuario de IAM*.
  +  `"Authorization": <string>`: información de firma de la versión 4 (SigV4) para firmar el AWS AppSync punto final. Para obtener más información sobre el proceso de firma, consulte [Tarea 4: Añadir la firma a la solicitud HTTP](https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html) en la *Referencia general de AWS*.

La solicitud HTTP de firma SigV4 incluye una URL canónica, que es el punto de enlace de AWS AppSync GraphQL con `/connect` anexado. La AWS región del punto final del servicio es la misma región en la que usas la AWS AppSync API y el nombre del servicio es «appsync». La solicitud HTTP para firmar es la siguiente:

```
{
  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",
  }
}
```

**Ejemplo**

```
{
  "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"
}
```

**Encabezados mediante cadena de consulta**

En primer lugar, un objeto JSON que contiene el `host` (punto final de AWS AppSync GraphQL) y los demás encabezados de autorización se convierte en una cadena. A continuación, esta cadena se codifica mediante la codificación base64. La cadena resultante codificada en base64 se añade a la WebSocket URL con un nombre para el parámetro de consulta. `header` La URL de solicitud resultante tiene el siguiente formato:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql?header=eyJBdXRob3JpemF0aW9uIjoiZXlKcmFXUWlPaUpqYkc1eGIzQTVlVzVNSzA5UVlYSXJNVEpIV0VGTFNYQmllVTVXTkhoc1FqaFBWVzlZTW5NMldsZHZQU0lzSW1Gc1p5STZJbEpUTWpVMkluMC5leUp6ZFdJaU9pSmhObU5tTWpjd055MHhOamd4TFRRMU5ESXRPV1l4T0MxbE5qWTBNVGcyTmpsa016WWlMQ0psZG1WdWRGOXBaQ0k2SW1Wa016TTVNbU5rTFdOallUTXROR00yT0MxaE5EWXlMVEpsWkdJM1pUTm1ZMkZqWmlJc0luUnZhMlZ1WDNWelpTSTZJbUZqWTJWemN5SXNJbk5qYjNCbElqb2lZWGR6TG1OdloyNXBkRzh1YzJsbmJtbHVMblZ6WlhJdVlXUnRhVzRpTENKaGRYUm9YM1JwYldVaU9qRTFOamswTlRjM01UZ3NJbWx6Y3lJNkltaDBkSEJ6T2x3dlhDOWpiMmR1YVhSdkxXbGtjQzVoY0MxemIzVjBhR1ZoYzNRdE1pNWhiV0Y2YjI1aGQzTXVZMjl0WEM5aGNDMXpiM1YwYUdWaGMzUXRNbDgzT0hZMFNWWmliVkFpTENKbGVIQWlPakUxTmprME5qRXpNakFzSW1saGRDSTZNVFUyT1RRMU56Y3lNQ3dpYW5ScElqb2lOVGd6WmpobVltTXRNemsyTVMwMFl6QTRMV0poWlRBdFl6UXlZMkl4TVRNNU5EWTVJaXdpWTJ4cFpXNTBYMmxrSWpvaU0zRmxhalZsTVhabU16ZDFOM1JvWld3MGRHOTFkREprTVd3aUxDSjFjMlZ5Ym1GdFpTSTZJbVZzYjNKNllXWmxJbjAuQjRjZEp0aDNLRk5wSjZpa1ZwN2U2RFJlZTk1VjZRaS16RUUyREpIN3NIT2wyenhZaTdmLVNtRUdvaDJBRDhlbXhRUllhakJ5ei1yRTRKaDBRT3ltTjJZcy1aSWtNcFZCVFBndS1UTVdEeU9IaERVbVVqMk9QODJ5ZVozd2xaQXRyX2dNNEx6alhVWG1JX0syeUdqdVhmWFRhYTFtdlFFQkcwbVFmVmQ3U2Z3WEItamN2NFJZVmk2ajI1cWdvdzlFdzUydWZ1clBxYUstM1dBS0czMktwVjhKNC1XZWpxOHQwYy15QTdzYjhFbkI1NTFiN1RVOTN1S1JpVlZLM0U1NU5rNUFEUG9hbV9XWUU0NWkzczVxVkFQXy1Jblc3NU5Vb09DR1RzUzhZV01mYjZlY0hZSi0xai1iekEyN3phVDlWamN0WG45YnlORlptS0xwQTJMY3h3IiwiaG9zdCI6ImV4YW1wbGUxMjM0NTY3ODkwMDAwLmFwcHN5bmMtYXBpLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tIn0=&payload=e30=
```

Es importante tener en cuenta que, además del objeto de encabezado codificado en base64, un objeto JSON vacío \$1\$1 también está codificado en base64 y se incluye como un parámetro de consulta independiente denominado en la URL. `payload` WebSocket

**Encabezados mediante `Sec-WebSocket-Protocol`**

Un objeto JSON que contiene el `host` y los otros encabezados de autorización se convierte en una cadena y, a continuación, se codifica mediante la codificación base64Url. La cadena codificada en base64Url resultante lleva el prefijo `header-`. Esta cadena con prefijo se utiliza luego como un nuevo subprotocolo, además de en el `Sec-WebSocket-Protocol` encabezado, al establecer la conexión con el `graphql-ws` punto final en tiempo real. WebSocket AWS AppSync 

La URL de solicitud resultante tiene el siguiente formato:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

El encabezado `Sec-WebSocket-Protocol` contiene el siguiente valor:

```
"sec-websocket-protocol" : ["graphql-ws", "header-ew0KICAiYWNjZXB0IjogImFwcGxpY2F0aW9uL2pzb24sIHRleHQvamF2YXNjcmlwdCIsDQogICJjb250ZW50LWVuY29kaW5nIjogImFtei0xLjAiLA0KICAiY29udGVudC10eXBlIjogImFwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9VVRGLTgiLA0KICAiaG9zdCI6ICJleGFtcGxlMTIzNDU2Nzg5MDAwMC5hcHBzeW5jLWFwaS51cy1lYXN0LTEuYW1hem9uYXdzLmNvbSIsDQogICJ4LWFtei1kYXRlIjogIjIwMjAwNDAxVDAwMTAxMFoiLA0KICAiWC1BbXotU2VjdXJpdHktVG9rZW4iOiAiQWdFWEFNUExFWjJsdVgyVmpFQW9hRG1Gd0xYTnZkWFJvWldGRVhBTVBMRWN3UlFJZ0FoOTdDbGpxN3dPUEw4S3N4UDNZdER1eWMvOWhBajhQaEo3RnZmMzhTZ29DSVFEaEpFWEFNUExFUHNwaW9PenRqKytwRWFnV0N2ZVpVaktFbjB6eVVoQkVYQU1QTEVqai8vLy8vLy8vLy84QkVYQU1QTEV4T0RrMk5EZ3lOemcxTlNJTW8xbVducEVTV1VvWXc0QmtLcUVGU3JtM0RYdUw4dytaYlZjNEpLakRQNHZVQ0tOUjZMZTlDOXBacDlQc1cwTm9GeTN2TEJVZEFYRVhBTVBMRU9WRzhmZVhmaUVFQSsxa2hnRksvd0V0d1IrOXpGN05hTU1Nc2UwN3dOMmdHMnRIMGVLTUVYQU1QTEVRWCtzTWJ5dFFvOGllcFA5UFpPemxac1NGYi9kUDVROGhrNllFWEFNUExFWWNLWnNUa0RBcTJ1S0ZROG1ZVVZBOUV0UW5OUmlGTEVZODNhS3ZHL3RxTFdObkdsU05WeDdTTWNmb3ZrRkRxUWFtbSs4OHkxT3d3QUVZSzdxY29jZVg2WjdHR2NhWXVJZkdwYVgyTUNDRUxlUXZaKzhXeEVnT25JZno3R1l2c1lOakxaU2FSblY0RytJTFkxRjBRTlc2NFM5TnZqK0J3RGczaHQyQ3JOdnB3alZZbGo5VTNubXhFMFVHNW5lODNMTDVoaHFNcG0yNWttTDdlblZndzJrUXptVTJpZDRJS3UwQy9XYW9EUnVPMkY1ekU2M3ZKYnhOOEFZczczMzgrNEI0SEJiNkJaNk9VZ2c5NlExNVJBNDEvZ0lxeGFWUHh5VHBEZlRVNUdmU0x4b2NkWWVuaXFxcEZNdFpHMm45ZDB1N0dzUU5jRmtOY0czcURabTR0RG84dFpidXltMGEyVmNGMkU1aEZFZ1hCYStYTEpDZlhpLzc3T3FBRWpQMHg3UWRrM0I0M3A4S0cvQmFpb1A1UnNWOHpCR3ZIMXpBZ3lQaGEyck43MC90VDEzeXJtUGQ1UVlFZnd6ZXhqS3JWNG1XSXVSZzhOVEhZU1pKVWFleUN3VG9tODBWRlVKWEcrR1lUVXl2NVcyMmFCY25vUkdpQ2lLRVlUTE9rZ1hlY2RLRlRIbWNJQWVqUTlXZWxyMGExOTZLcTg3dzVLTk1Da2NDR0Zud0JORkxtZm5icE5xVDZyVUJ4eHMzWDVudFg5ZDhIVnRTWUlOVHNHWFhNWkNKN2ZuYldhamhnL2FveDBGdEhYMjFlRjZxSUdUOGoxeitsMm9wVStnZ3dVZ2toVVVnQ0gyVGZxQmorTUxNVlZ2cGdxSnNQS3Q1ODJjYUZLQXJJRkl2Tys5UXVweExuRUgyaHowNFRNVGZuVTZiUUM2ejFidVZlN2grdE9MbmgxWVBGc0xRODhhbmliLzdUVEM4azlEc0JUcTBBU2U4UjJHYlNFc21POXFiYk13Z0VhWVVoT0t0R2V5UXNTSmRoU2s2WHhYVGhyV0w5RW53QkNYRGtJQ01xZG50QXh5eU05bldzWjRiTDlKSHFFeGdXVW1mV0NoelBGQXFuM0Y0eTg5NlVxSFRaeGxxM1dHeXBuNUhIY2VtMkhxZjNJVnhLSDFpbmhxZFZ0a3J5RWlUV3JJN1pkamJxbnFSYmwrV2d0UHRLT093ZURsQ2FSczNSMnFYY2JOZ1ZobGVNazRJV25GOEQxNjk1QWVuVTFMd0hqT0pMa0NqeGdORmlXQUZFUEg5YUVYQU1QTEV4QT09IiwNCiAgIkF1dGhvcml6YXRpb24iOiAiQVdTNC1ITUFDLVNIQTI1NiBDcmVkZW50aWFsPVhYWFhYWFhYWFhYWFhYWFhYWFgvMjAyMDA0MDEvdXMtZWFzdC0xL2FwcHN5bmMvYXdzNF9yZXF1ZXN0LCBTaWduZWRIZWFkZXJzPWFjY2VwdDtjb250ZW50LWVuY29kaW5nO2NvbnRlbnQtdHlwZTtob3N0O3gtYW16LWRhdGU7eC1hbXotc2VjdXJpdHktdG9rZW4sIFNpZ25hdHVyZT04M0VYQU1QTEViY2MxZmUzZWU2OWY3NWNkNWViYmY0Y2I0ZjE1MGU0Zjk5Y2VjODY5ZjE0OWM1RVhBTVBMRWRjIg0KfQ"]
```

**Encabezados mediante encabezados HTTP estándar**

En este método, el host y el resto de la información de autorización se transmiten mediante encabezados HTTP estándar al establecer la WebSocket conexión con el AWS AppSync punto final en tiempo real. La URL de solicitud resultante tiene el siguiente formato:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

Los encabezados de solicitud incluirían lo siguiente:

```
"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 firmar la solicitud con un dominio 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",
  }
}
```

**Ejemplo**

```
{
  "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 solicitud con cadena de consulta**

```
wss://api.example.com/graphql?header=eyEXAMPLEHQiOiJhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L2phdmFEXAMPLEQiLCJjb250ZW50LWVuY29kaW5nIjoEXAMPLEEuMCIsImNvbnRlbnQtdHlwZSI6ImFwcGxpY2F0aW9EXAMPLE47IGNoYXJzZXQ9VVRGLTgiLCJob3N0IjoiZXhhbXBsZEXAMPLENjc4OTAwMDAuYXBwc3luYy1hcGkudXMtZWFzdC0xLmFtYEXAMPLEcy5jb20iLCJ4LWFtei1kYXRlIjoiMjAyMDA0MDFUMDAxMDEwWiIsIlgtEXAMPLElY3VyaXR5LVRva2VuIjoiQWdvSmIzSnBaMmx1WDJWakVBb2FEbUZ3TFhOdmRYUm9aV0Z6ZEMweUlrY3dSUUlnQWg5N0NsanE3d09QTDhLc3hQM1l0RHV5Yy85aEFqOFBoSjdGdmYzOFNnb0NJUURoSllKYkpsbmpQc3Bpb096dGorK3BFYWdXQ3ZlWlVqS0VuMHp5VWhCbXhpck5CUWpqLy8vLy8vLy8vLzhCRUFBYUREY3hPRGsyTkRneU56ZzFOU0lNbzFtV25wRVNXVW9ZdzRCa0txRUZTcm0zRFh1TDh3K1piVmM0SktqRFA0dlVDS05SNkxlOUM5cFpwOVBzVzBOb0Z5M3ZMQlVkQVh3dDZQSld1T1ZHOGZlWGZpRUVBKzFraGdGSy93RXR3Uis5ekY3TmFNTU1zZTA3d04yZ0cydEgwZUtNVFhuOEF3QVFYK3NNYnl0UW84aWVwUDlQWk96bFpzU0ZiL2RQNVE4aGs2WWpHVGFMMWVZY0tac1RrREFxMnVLRlE4bVlVVkE5RXRRbk5SaUZMRVk4M2FLdkcvdHFMV05uR2xTTlZ4N1NNY2ZvdmtGRHFRYW1tKzg4eTFPd3dBRVlLN3Fjb2NlWDZaN0dHY2FZdUlmR3BhWDJNQ0NFTGVRdlorOFd4RWdPbklmejdHWXZzWU5qTFpTYVJuVjRHK0lMWTFGMFFOVzY0UzlOdmorQndEZzNodDJDck52cHdqVllsajlVM25teEUwVUc1bmU4M0xMNWhocU1wbTI1a21MN2VuVmd3MmtRem1VMmlkNElLdTBDL1dhb0RSdU8yRjV6RTYzdkpieE44QVlzNzMzOCs0QjRIQmI2Qlo2T1VnZzk2UTE1UkE0MS9nSXF4YVZQeHlUcERmVFU1R2ZTTHhvY2RZZW5pcXFwRk10WkcybjlkMHU3R3NRTmNGa05jRzNxRFptNHREbzh0WmJ1eW0wYTJWY0YyRTVoRkVnWEJhK1hMSkNmWGkvNzdPcUFFalAweDdRZGszQjQzcDhLRy9CYWlvUDVSc1Y4ekJHdkgxekFneVBoYTJyTjcwL3RUMTN5cm1QZDVRWUVmd3pleGpLclY0bVdJdVJnOE5USFlTWkpVYWV5Q3dUb204MFZGVUpYRytHWVRVeXY1VzIyYUJjbm9SR2lDaUtFWVRMT2tnWGVjZEtGVEhtY0lBZWpROVdlbHIwYTE5NktxODd3NUtOTUNrY0NHRm53Qk5GTG1mbmJwTnFUNnJVQnh4czNYNW50WDlkOEhWdFNZSU5Uc0dYWE1aQ0o3Zm5iV2FqaGcvYW94MEZ0SFgyMWVGNnFJR1Q4ajF6K2wyb3BVK2dnd1Vna2hVVWdDSDJUZnFCaitNTE1WVnZwZ3FKc1BLdDU4MmNhRktBcklGSXZPKzlRdXB4TG5FSDJoejA0VE1UZm5VNmJRQzZ6MWJ1VmU3aCt0T0xuaDFZUEZzTFE4OGFuaWIvN1RUQzhrOURzQlRxMEFTZThSMkdiU0VzbU85cWJiTXdnRWFZVWhPS3RHZXlRc1NKZGhTazZYeFhUaHJXTDlFbndCQ1hEa0lDTXFkbnRBeHl5TTluV3NaNGJMOUpIcUV4Z1dVbWZXQ2h6UEZBcW4zRjR5ODk2VXFIVFp4bHEzV0d5cG41SEhjZW0ySHFmM0lWeEtIMWluaHFkVnRrcnlFaVRXckk3WmRqYnFucVJibCtXZ3RQdEtPT3dlRGxDYVJzM1IycVhjYk5nVmhsZU1rNElXbkY4RDE2OTVBZW5VMUx3SGpPSkxrQ2p4Z05GaVdBRkVQSDlhTklhcXMvWnhBPT0iLCJBdXRob3JpemF0aW9uIjoiQVdTNC1ITUFDLVNIQTI1NiBDcmVkZW50aWFsPVhYWFhYWFhYWFhYWFhYWFhYWFgvMjAxOTEwMDIvdXMtZWFzdC0xEXAMPLE5bmMvYXdzNF9yZXF1ZXN0LCBTaWduZWRIZWFkZXJzPWFjY2VwdDtjb250ZWEXAMPLE29kaW5nO2NvbnRlbnQtdHlwZTtob3EXAMPLEW16LWRhdGU7eC1hbXotc2VjdXJpdHktdG9rZW4sIFNpZ25hdHVyZT04MzE4EXAMPLEiY2MxZmUzZWU2OWY3NWNkEXAMPLE0Y2I0ZjE1MGU0Zjk5Y2VjODY5ZjE0OWM1ZDAzNDEXAMPLEn0=&payload=e30=
```

**nota**  
Una WebSocket conexión puede tener varias suscripciones (incluso con distintos modos de autenticación). Una forma de implementarlo consiste en crear una WebSocket conexión para la primera suscripción y, a continuación, cerrarla cuando se anule el registro de la última suscripción. Puedes optimizarlo esperando unos segundos antes de cerrar la WebSocket conexión, en caso de que la aplicación se suscriba inmediatamente después de anular el registro de la última suscripción. Para un ejemplo de aplicación móvil, al cambiar de una pantalla a otra, al *desmontar* un evento, se detiene una suscripción y al *montar* un evento, se inicia una suscripción distinta.

### Autorización Lambda
<a name="lambda-auth"></a>

#### Encabezado de autorización Lambda
<a name="lambda-auth-list"></a>

**Contenido del encabezado**
+  `"Authorization": <string>`: el valor por el que se pasa como `authorizationToken`.
+  `"host": <string>`: el host del punto final de AWS AppSync GraphQL o tu nombre de dominio personalizado.

**Ejemplo**

```
{
    "Authorization":"M0UzQzM1MkQtMkI0Ni00OTZCLUI1NkQtMUM0MTQ0QjVBRTczCkI1REEzRTIxLTk5NzItNDJENi1BQjMwLTFCNjRFNzQ2NzlCNQo=",
    "host":"example1234567890000.appsync-api.us-east-1.amazonaws.com"
}
```

**Encabezados mediante cadena de consulta**

En primer lugar, un objeto JSON que contiene el `host` y la `Authorization` se convierte en una cadena. A continuación, esta cadena se codifica mediante la codificación base64. La cadena codificada en base64 resultante se agrega como un parámetro de consulta con el nombre de la WebSocket URL `header` para establecer la conexión con el punto final en tiempo real. AWS AppSync La URL de solicitud resultante tiene el siguiente formato:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql?header=eyJBdXRob3JpemF0aW9uIjoiZXlKcmFXUWlPaUpqYkc1eGIzQTVlVzVNSzA5UVlYSXJNVEpIV0VGTFNYQmllVTVXTkhoc1FqaFBWVzlZTW5NMldsZHZQU0lzSW1Gc1p5STZJbEpUTWpVMkluMC5leUp6ZFdJaU9pSmhObU5tTWpjd055MHhOamd4TFRRMU5ESXRPV1l4T0MxbE5qWTBNVGcyTmpsa016WWlMQ0psZG1WdWRGOXBaQ0k2SW1Wa016TTVNbU5rTFdOallUTXROR00yT0MxaE5EWXlMVEpsWkdJM1pUTm1ZMkZqWmlJc0luUnZhMlZ1WDNWelpTSTZJbUZqWTJWemN5SXNJbk5qYjNCbElqb2lZWGR6TG1OdloyNXBkRzh1YzJsbmJtbHVMblZ6WlhJdVlXUnRhVzRpTENKaGRYUm9YM1JwYldVaU9qRTFOamswTlRjM01UZ3NJbWx6Y3lJNkltaDBkSEJ6T2x3dlhDOWpiMmR1YVhSdkxXbGtjQzVoY0MxemIzVjBhR1ZoYzNRdE1pNWhiV0Y2YjI1aGQzTXVZMjl0WEM5aGNDMXpiM1YwYUdWaGMzUXRNbDgzT0hZMFNWWmliVkFpTENKbGVIQWlPakUxTmprME5qRXpNakFzSW1saGRDSTZNVFUyT1RRMU56Y3lNQ3dpYW5ScElqb2lOVGd6WmpobVltTXRNemsyTVMwMFl6QTRMV0poWlRBdFl6UXlZMkl4TVRNNU5EWTVJaXdpWTJ4cFpXNTBYMmxrSWpvaU0zRmxhalZsTVhabU16ZDFOM1JvWld3MGRHOTFkREprTVd3aUxDSjFjMlZ5Ym1GdFpTSTZJbVZzYjNKNllXWmxJbjAuQjRjZEp0aDNLRk5wSjZpa1ZwN2U2RFJlZTk1VjZRaS16RUUyREpIN3NIT2wyenhZaTdmLVNtRUdvaDJBRDhlbXhRUllhakJ5ei1yRTRKaDBRT3ltTjJZcy1aSWtNcFZCVFBndS1UTVdEeU9IaERVbVVqMk9QODJ5ZVozd2xaQXRyX2dNNEx6alhVWG1JX0syeUdqdVhmWFRhYTFtdlFFQkcwbVFmVmQ3U2Z3WEItamN2NFJZVmk2ajI1cWdvdzlFdzUydWZ1clBxYUstM1dBS0czMktwVjhKNC1XZWpxOHQwYy15QTdzYjhFbkI1NTFiN1RVOTN1S1JpVlZLM0U1NU5rNUFEUG9hbV9XWUU0NWkzczVxVkFQXy1Jblc3NU5Vb09DR1RzUzhZV01mYjZlY0hZSi0xai1iekEyN3phVDlWamN0WG45YnlORlptS0xwQTJMY3h3IiwiaG9zdCI6ImV4YW1wbGUxMjM0NTY3ODkwMDAwLmFwcHN5bmMtYXBpLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tIn0=&payload=e30=
```

Es importante tener en cuenta que, además del objeto de encabezado codificado en base64, un objeto JSON vacío \$1\$1 también está codificado en base64 y se incluye como un parámetro de consulta independiente denominado en la URL. `payload` WebSocket

**Encabezados mediante `Sec-WebSocket-Protocol`**

Un objeto JSON que contiene el `host` y la `Authorization` se convierte en una cadena y, a continuación, se codifica mediante la codificación base64Url. La cadena codificada en base64Url resultante lleva el prefijo `header-`. Esta cadena con prefijo se utiliza luego como un nuevo subprotocolo, además de en el `Sec-WebSocket-Protocol` encabezado, al establecer la conexión con el `graphql-ws` punto final en tiempo real. WebSocket AWS AppSync 

La URL de solicitud resultante tiene el siguiente formato:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

El encabezado `Sec-WebSocket-Protocol` contiene el siguiente valor:

```
"sec-websocket-protocol" : ["graphql-ws", "header-ewogICAgImhvc3QiOiJleGFtcGxlMTIzNDU2Nzg5MDAwMC5hcHBzeW5jLWFwaS51cy1lYXN0LTEuYW1hem9uYXdzLmNvbSIsCiAgICAieC1hcGkta2V5IjoiZGEyLTEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Igp9"]
```

**Encabezados mediante encabezados HTTP estándar**

En este método, la información del host y de la autorización se transmite mediante encabezados HTTP estándar al establecer la WebSocket conexión con el AWS AppSync punto final en tiempo real. La URL de solicitud resultante tiene el siguiente formato:

```
wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql
```

Los encabezados de solicitud incluirían lo siguiente:

```
"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"
```

## Funcionamiento en tiempo real WebSocket
<a name="real-time-websocket-operation"></a>

Tras iniciar un WebSocket apretón de manos exitoso AWS AppSync, el cliente debe enviar un mensaje posterior al que conectarse AWS AppSync para realizar diferentes operaciones. Estos mensajes requieren los siguientes datos:
+  `type`: el tipo de operación.
+  `id`: un identificador único para la suscripción. Recomendamos usar un UUID para este fin.
+  `payload`: la carga útil asociada según el tipo de operación.

El campo `type` es el único campo obligatorio; los campos `id` y `payload` son opcionales.

### Secuencia de eventos
<a name="sequence-of-events"></a>

Para iniciar, establecer, registrar y procesar correctamente la solicitud de suscripción, el cliente debe pasar por la siguiente secuencia:

1. Inicializar conexión (`connection_init`)

1. Reconocimiento de conexión (`connection_ack`)

1. Registro de suscripción (`start`)

1. Reconocimiento de suscripción (`start_ack`)

1. Procesamiento de suscripción (`data`)

1. Anulación del registro de suscripción (`stop`)

## Mensaje connection init
<a name="connection-init-message"></a>

(Opcional) Tras un apretón de manos exitoso, el cliente puede enviar el `connection_init` mensaje para empezar a comunicarse con el AWS AppSync terminal en tiempo real. El mensaje es una cadena obtenida mediante la representación en forma de cadena del objeto JSON como se indica a continuación:

```
{ "type": "connection_init" }
```

## Mensaje de confirmación de conexión
<a name="connection-acknowledge-message"></a>

Después de enviar el mensaje `connection_init`, el cliente debe esperar el mensaje `connection_ack`. Todos los mensajes enviados antes de recibir `connection_ack` se omitirán. El mensaje debería decir lo siguiente:

```
{
  "type": "connection_ack",
  "payload": {
    // Time in milliseconds waiting for ka message before the client should terminate the WebSocket connection
    "connectionTimeoutMs": 300000
  }
}
```

## Mensaje Keep-alive
<a name="keep-alive-message"></a>

Además del mensaje de confirmación de conexión, el cliente recibe periódicamente mensajes keep-alive. Si el cliente no recibe un mensaje de mantenimiento activo dentro del período de espera de la conexión, debe cerrar la conexión. AWS AppSync sigue enviando estos mensajes y gestionando las suscripciones registradas hasta que cierra la conexión automáticamente (después de 24 horas). Los mensajes keep-alive son latidos y no necesitan reconocimiento por parte del cliente.

```
{ "type": "ka" }
```

## Mensaje de registro de suscripción
<a name="subscription-registration-message"></a>

Una vez que el cliente reciba un `connection_ack` mensaje, podrá enviar los mensajes de registro de la suscripción a AWS AppSync. Este tipo de mensaje es un objeto JSON representado en forma de cadena que contiene los siguientes campos:
+  `"id": <string>`: el ID de la suscripción. Este ID debe ser único para cada suscripción; de lo contrario, el servidor devuelve un error que indica que el ID de suscripción está duplicado.
+  `"type": "start"`: un parámetro `<string>` constante.
+  `"payload": <Object>`: un objeto que contiene la información relevante para la suscripción.
  +  `"data": <string>`: un objeto JSON representado en forma de cadena que contiene una consulta de GraphQL y variables.
    +  `"query": <string>`: operación de GraphQL.
    +  `"variables": <Object>`: un objeto que contiene las variables para la consulta.
  +  `"extensions": <Object>`: un objeto que contiene un objeto de autorización.
+  `"authorization": <Object>`: un objeto que contiene los campos necesarios para la autorización.

### Objeto de autorización para el registro de suscripción
<a name="authorization-object-for-subscription-registration"></a>

Las mismas reglas de la sección [Formato de parámetros de encabezado basado en el modo AWS AppSync de autorización de la API](#header-parameter-format-based-on-appsync-api-authorization-mode) se aplican al objeto de autorización. La única excepción es para IAM, donde la información de la firma SigV4 es ligeramente diferente. Para obtener más información, consulte el ejemplo de IAM.

Ejemplo de uso de grupos de usuarios de 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"
}
```

Ejemplo de uso de 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"
}
```

Ejemplo de uso de un nombre de dominio 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"
}
```

La firma SigV4 no necesita que se anexe `/connect` a la URL y la operación de GraphQL representada en forma de cadena JSON reemplaza a `data`. A continuación, se muestra un ejemplo de una solicitud de firma 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",
  }
}
```

## Mensaje de confirmación de suscripción
<a name="subscription-acknowledge-message"></a>

Tras enviar el mensaje de inicio de la suscripción, el cliente debe esperar AWS AppSync a que se envíe el `start_ack` mensaje. El mensaje `start_ack` indica que la suscripción se ha realizado correctamente.

Ejemplo de reconocimiento de suscripción:

```
{
  "type": "start_ack",
  "id": "eEXAMPLE-cf23-1234-5678-152EXAMPLE69"
}
```

## Mensaje de error
<a name="error-message"></a>

Si se produce un error en el registro de suscripción o el inicio de la suscripción, o bien si se termina una suscripción desde el servidor, el servidor envía un mensaje de error al cliente. Si el error se produce durante el tiempo de inicio de la conexión, el servidor cerrará la conexión.
+  `"type": "error"`: un parámetro `<string>` constante.
+  `"id": <string>`: el ID de la suscripción registrada correspondiente, si procede.
+  `"payload" <Object>`: un objeto que contiene la información de error correspondiente.

Ejemplo:

```
{
  "type": "error",
  "payload": {
    "errors": [
      {
        "errorType": "LimitExceededError",
        "message": "Rate limit exceeded"
      }
    ]
  }
}
```

## Procesamiento de mensajes de datos
<a name="processing-data-messages"></a>

Cuando un cliente envía una mutación, AWS AppSync identifica a todos los suscriptores interesados en ella y envía un `"type":"data"` mensaje a cada uno de ellos utilizando la suscripción correspondiente a la operación `id` de `"start"` suscripción. Se espera que el cliente realice un seguimiento del `id` de suscripción que envía para que cuando se reciba un mensaje de datos, el cliente pueda asociarlo con la suscripción correspondiente.
+  `"type": "data"`: un parámetro `<string>` constante.
+  `"id": <string>`: el ID de la suscripción registrada correspondiente.
+  `"payload" <Object>`: un objeto que contiene la información relevante para la suscripción.

Ejemplo:

```
{
  "type": "data",
  "id": "ee849ef0-cf23-4cb8-9fcb-152ae4fd1e69",
  "payload": {
    "data": {
      "onCreateMessage": {
        "__typename": "Message",
        "message": "test"
      }
    }
  }
}
```

## Mensaje de anulación de registro de suscripción
<a name="subscription-unregistration-message"></a>

Cuando la aplicación quiere dejar de escuchar los eventos de suscripción, el cliente debe enviar un mensaje con el siguiente objeto JSON representado en forma de cadena:
+  `"type": "stop"`: un parámetro `<string>` constante.
+  `"id": <string>`: el ID de la suscripción cuyo registro se va a cancelar.

Ejemplo:

```
{
  "type":"stop",
  "id":"ee849ef0-cf23-4cb8-9fcb-152ae4fd1e69"
}
```

AWS AppSync devuelve un mensaje de confirmación con el siguiente objeto JSON en cadena:
+  `"type": "complete"`: un parámetro `<string>` constante.
+  `"id": <string>`: el ID de la suscripción cuyo registro se anuló.

Una vez que el cliente reciba el mensaje de confirmación, no recibirá más mensajes para esta suscripción en particular.

Ejemplo:

```
{
  "type":"complete",
  "id":"eEXAMPLE-cf23-1234-5678-152EXAMPLE69"
}
```

## Desconectando el WebSocket
<a name="disconnecting-the-websocket"></a>

Antes de desconectarse, para evitar la pérdida de datos, el cliente debe disponer de la lógica necesaria para comprobar que actualmente no se está realizando ninguna operación a través de la WebSocket conexión. Se debe anular el registro de todas las suscripciones antes de desconectarse de. WebSocket