

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Utilisation d'abonnements pour des applications de données en temps réel dans AWS AppSync
<a name="aws-appsync-real-time-data"></a>

**Important**  
À WebSockets partir du 13 mars 2025, vous pouvez créer une PubSub API en temps réel alimentée par AWS AppSync Events. Pour plus d'informations, consultez la section [Publier des événements via WebSocket](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) le *Guide du développeur d'AWS AppSync événements*.

AWS AppSyncvous permet d'utiliser des abonnements pour mettre en œuvre des mises à jour d'applications en direct, des notifications push, etc. Lorsque les clients invoquent les opérations d'abonnement GraphQL, une WebSocket connexion sécurisée est automatiquement établie et maintenue par. AWS AppSync Les applications peuvent ensuite distribuer des données en temps réel à partir d'une source de données aux abonnés tout en gérant en AWS AppSync permanence les exigences de connexion et de dimensionnement de l'application. Les sections suivantes vous montreront comment AWS AppSync fonctionnent les abonnements.

## Directives d'abonnement au schéma GraphQL
<a name="graphql-schema-subscription-directives"></a>

Les abonnements AWS AppSync sont invoqués en réponse à une mutation. Cela signifie que vous pouvez créer n'importe quelle source de données en temps AWS AppSync réel en spécifiant une directive de schéma GraphQL sur une mutation.

Les bibliothèques AWS Amplify clientes gèrent automatiquement la gestion des connexions par abonnement. Les bibliothèques utilisent Pure WebSockets comme protocole réseau entre le client et le service.

**Note**  
Pour contrôler l'autorisation au moment de la connexion à un abonnement, vous pouvez utiliser Gestion des identités et des accès AWS (IAM) AWS Lambda, les groupes d'identités Amazon Cognito ou les groupes d'utilisateurs Amazon Cognito pour l'autorisation au niveau du champ. Pour des contrôles d'accès précis sur les abonnements, vous pouvez associer des résolveurs à vos champs d'abonnement et exécuter une logique en utilisant l'identité de l'appelant et les sources de données. AWS AppSync Pour de plus amples informations, veuillez consulter [Configuration de l'autorisation et de l'authentification pour sécuriser votre GraphQL APIs](security-authz.md).

Les abonnements sont déclenchés à partir des mutations et le jeu de sélection de mutations est envoyé aux abonnés.

L'exemple suivant montre comment utiliser les abonnements GraphQL. Il ne spécifie pas de source de données, car celle-ci peut être Lambda, Amazon DynamoDB ou Amazon Service. OpenSearch 

Pour commencer à utiliser les abonnements, vous devez ajouter un point d'entrée d'abonnement à votre schéma comme suit :

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

Supposons que vous disposez d'un site de blog et que vous souhaitez vous abonner à de nouveaux blogs et à des modifications de blogs existants. Pour ce faire, vous devez ajouter la définition `Subscription` suivante à votre schéma :

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

Supposons encore que vous disposez des mutations suivantes :

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

Vous pouvez transformer ces champs en temps réel en ajoutant une directive `@aws_subscribe(mutations: ["mutation_field_1", "mutation_field_2"])` pour chacun des abonnements pour lesquels vous souhaitez recevoir des notifications, comme suit :

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

Comme il `@aws_subscribe(mutations: ["",..,""])` prend un ensemble d'entrées de mutation, vous pouvez spécifier plusieurs mutations, ce qui déclenche un abonnement. Si vous vous abonnez à partir d'un client, votre requête GraphQL peut ressembler à ce qui suit :

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

Cette requête d'abonnement est nécessaire pour les connexions client et l'outillage.

Avec le WebSockets client pur, le filtrage des ensembles de sélection est effectué par client, car chaque client peut définir son propre ensemble de sélection. Dans ce cas, le jeu de sélection d'abonnement doit être un sous-ensemble du jeu de sélection de mutation. Par exemple, un abonnement `addedPost{author title}` lié à la mutation ne `addPost(...){id author title url version}` reçoit que l'auteur et le titre de l'article. Il ne reçoit pas les autres champs. Cependant, si la mutation n'avait pas l'auteur dans son ensemble de sélection, l'abonné obtiendrait une valeur `null` pour le champ auteur (ou une erreur dans le cas où le champ auteur est défini comme « required/not-null » dans le schéma).

L'ensemble de sélection des abonnements est essentiel lors de l'utilisation de Pure WebSockets. Si un champ n'est pas explicitement défini dans l'abonnement, il AWS AppSync ne renvoie pas le champ.

Dans l'exemple précédent, les abonnements n'avaient pas d'arguments. Supposons que votre schéma ressemble à ce qui suit :

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

Dans ce cas, votre client définit un abonnement ainsi :

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

Le type de retour d'un champ `subscription` dans votre schéma doit correspondre au type de retour du champ de mutation correspondant. L'exemple précédent illustrait cela avec `addPost` et `addedPost` qui ont été renvoyés en tant que type de `Post`.

Pour configurer les abonnements sur le client, voir[Création d'une application cliente à l'aide du client Amplify](building-a-client-app.md).

## Utilisation d'arguments d'abonnement
<a name="using-subscription-arguments"></a>

Pour utiliser les abonnements GraphQL, il est important de comprendre quand et comment utiliser les arguments. Vous pouvez apporter des modifications subtiles pour modifier comment et quand informer les clients des mutations survenues. Pour ce faire, consultez l'exemple de schéma du chapitre de démarrage rapide, qui crée « Todos ». Pour cet exemple de schéma, les mutations suivantes sont définies :

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

Dans l'exemple par défaut, les clients peuvent s'abonner aux mises à jour de n'importe quel produit en `Todo` utilisant le `onUpdateTodo` `subscription` paramètre sans argument :

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

Vous pouvez filtrer votre `subscription` en utilisant ses arguments. Par exemple, pour déclencher un uniquement `subscription` lorsqu'un fichier `todo` contenant un élément spécifique `ID` est mis à jour, spécifiez la `ID` valeur :

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

Vous pouvez également transmettre plusieurs arguments. Par exemple, ce qui suit `subscription` montre comment être informé de toute `Todo` mise à jour à un endroit et à une heure spécifiques :

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

Notez que tous les arguments sont facultatifs. Si vous ne spécifiez aucun argument dans votre application`subscription`, vous serez abonné à toutes les `Todo` mises à jour effectuées dans votre application. Cependant, vous pouvez mettre à jour votre définition `subscription` de champ pour exiger l'`ID`argument. Cela forcerait la réponse d'un `todo` s spécifique `todo` au lieu de tous :

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

### La valeur null de l'argument a une signification
<a name="argument-null-value-has-meaning"></a>

Lorsque vous effectuez une requête d'abonnement dans AWS AppSync, la valeur d'un `null` argument filtrera les résultats différemment de l'omission complète de l'argument.

Revenons à l'exemple d'API todos où nous pourrions créer des todos. Consultez l'exemple de schéma du chapitre de démarrage rapide.

Modifions notre schéma pour inclure un nouveau `owner` champ, sur le `Todo` type, qui décrit le propriétaire. Le `owner` champ n'est pas obligatoire et peut uniquement être activé`UpdateTodoInput`. Consultez la version simplifiée suivante du schéma :

```
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"])
}
```

L'abonnement suivant renvoie toutes les `Todo` mises à jour :

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

Si vous modifiez l'abonnement précédent pour ajouter l'argument de champ`owner: null`, vous posez maintenant une autre question. Cet abonnement enregistre désormais le client pour qu'il soit informé de toutes les `Todo` mises à jour pour lesquelles aucun propriétaire n'a été fourni.

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

**Note**  
**Depuis le 1er janvier 2022, MQTT over n' WebSockets est plus disponible en tant que protocole pour les abonnements GraphQL dans. AWS AppSync APIs Pure WebSockets est le seul protocole pris en charge dans AWS AppSync.**  
Les clients basés sur le AWS AppSync SDK ou les bibliothèques Amplify, publiés après novembre 2019, utilisent automatiquement WebSockets pure par défaut. La mise à niveau des clients vers la dernière version leur permet AWS AppSync d'utiliser le WebSockets moteur pur.  
Pure WebSockets propose une charge utile plus importante (240 Ko), une plus grande variété d'options client et des CloudWatch indicateurs améliorés. Pour plus d'informations sur l'utilisation de WebSocket clients purs, consultez[Création d'un WebSocket client en temps réel dans AWS AppSync](real-time-websocket-client.md).

# Création d'un générique pub/sub APIs alimenté par serverless WebSockets dans AWS AppSync
<a name="aws-appsync-real-time-create-generic-api-serverless-websocket"></a>

**Important**  
À WebSockets partir du 13 mars 2025, vous pouvez créer une PubSub API en temps réel alimentée par AWS AppSync Events. Pour plus d'informations, consultez la section [Publier des événements via WebSocket](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) le *Guide du développeur d'AWS AppSync événements*.

Certaines applications ne nécessitent que des applications simples WebSocket APIs lorsque les clients écoutent une chaîne ou un sujet spécifique. Les données JSON génériques ne présentant aucune forme spécifique ni aucune exigence typographique stricte peuvent être transmises aux clients écoutant l'un de ces canaux selon un schéma purement et simple de publication/abonnement (pub/sub).

 AWS AppSync À utiliser pour implémenter pub/sub WebSocket APIs des applications simples avec peu ou pas de connaissances GraphQL en quelques minutes en générant automatiquement du code GraphQL à la fois sur le backend de l'API et côté client.

## Création et configuration de pub-sub APIs
<a name="aws-appsync-real-time-enhanced-filtering-using-pub-sub-apis"></a>

Pour commencer, procédez comme suit : 

1. Connectez-vous à la [AppSync console AWS Management Console et ouvrez-la](https://console.aws.amazon.com/appsync/).

   1. Dans le **Tableau de bord**, choisissez **Créer une API**.

1. Sur l'écran suivant, choisissez **Créer une API en temps réel**, puis cliquez sur **Suivant**.

1. Entrez un nom convivial pour votre pub/sub API.

1. Vous pouvez activer les fonctionnalités d'[API privées](https://docs.aws.amazon.com/appsync/latest/devguide/using-private-apis.html), mais nous vous recommandons de les désactiver pour le moment. Choisissez **Suivant**.

1. Vous pouvez choisir de générer automatiquement une pub/sub API fonctionnelle à l'aide de WebSockets. Nous vous recommandons également de désactiver cette fonctionnalité pour le moment. Choisissez **Suivant**.

1. Choisissez **Create API**, puis attendez quelques minutes. Une nouvelle API AWS AppSync pub/sub préconfigurée sera créée dans votre compte. AWS 

L'API utilise des AWS AppSync résolveurs locaux intégrés (pour plus d'informations sur l'utilisation des résolveurs locaux, voir [Tutoriel : résolveurs locaux](https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-local-resolvers-js.html) dans le *guide du AWS AppSync développeur*) pour gérer plusieurs pub/sub canaux et WebSocket connexions temporaires, qui fournissent et filtrent automatiquement les données aux clients abonnés en fonction uniquement du nom du canal. Les appels d'API sont autorisés à l'aide d'une clé d'API.

Une fois l'API déployée, quelques étapes supplémentaires vous sont proposées pour générer du code client et l'intégrer à votre application client. À titre d'exemple sur la façon d'intégrer rapidement un client, ce guide utilisera une simple application Web React.

1. Commencez par créer une application React standard à l'aide de [NPM](https://www.npmjs.com/get-npm) sur votre machine locale :

   ```
   $ npx create-react-app mypubsub-app 
   $ cd mypubsub-app
   ```
**Note**  
Cet exemple utilise les [bibliothèques Amplify](https://docs.amplify.aws/lib/) pour connecter les clients à l'API principale. Cependant, il n'est pas nécessaire de créer un projet Amplify CLI localement. Bien que React soit le client de choix dans cet exemple, les bibliothèques Amplify prennent également en charge les clients iOS, Android et Flutter, offrant les mêmes fonctionnalités dans ces différents environnements d'exécution. [Les clients Amplify pris en charge fournissent des abstractions simples pour interagir avec les backends d'API AWS AppSync GraphQL avec quelques lignes de code, y compris des WebSocket fonctionnalités intégrées entièrement compatibles avec le protocole en temps réel :AWS AppSync WebSocket ](https://docs.aws.amazon.com/appsync/latest/devguide/real-time-websocket-client.html)  

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

1. Dans la AWS AppSync console **JavaScript**, sélectionnez puis **Télécharger pour télécharger** un seul fichier contenant les détails de configuration de l'API et le code d'opérations GraphQL généré.

1. Copiez le fichier téléchargé dans le `/src` dossier de votre projet React.

1. Remplacez ensuite le contenu du `src/App.js` fichier standard existant par l'exemple de code client disponible dans la console.

1. Utilisez la commande suivante pour démarrer l'application localement :

   ```
   $ npm start
   ```

1. Pour tester l'envoi et la réception de données en temps réel, ouvrez deux fenêtres de navigateur et accédez-y*localhost:3000*. L'exemple d'application est configuré pour envoyer des données JSON génériques à un canal codé en dur nommé*robots*.

1.  Dans l'une des fenêtres du navigateur, entrez le blob JSON suivant dans la zone de texte, puis cliquez sur **Soumettre** : 

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

Les deux instances de navigateur sont abonnées au *robots* canal et reçoivent les données publiées en temps réel, affichées en bas de l'application Web :

![\[Exemple d'application React pour pub/sub API\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/images/pub-sub-react.png)


Tout le code d'API GraphQL nécessaire, y compris le schéma, les résolveurs et les opérations, est généré automatiquement pour permettre un cas d'utilisation générique pub/sub . Sur le backend, les données sont publiées sur le point AWS AppSync de terminaison en temps réel avec une mutation GraphQL telle que la suivante :

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

Les abonnés accèdent aux données publiées envoyées au canal temporaire spécifique avec un abonnement GraphQL associé :

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

## Implémentation de pub-sub APIs dans les applications existantes
<a name="aws-appsync-real-time-enhanced-filtering-existing-apps"></a>

Si vous devez simplement implémenter une fonctionnalité en temps réel dans une application existante, cette configuration d' pub/sub API générique peut être facilement intégrée à n'importe quelle application ou technologie d'API. Bien qu'il y ait des avantages à utiliser un point de terminaison d'API unique pour accéder, manipuler et combiner en toute sécurité des données provenant d'une ou de plusieurs sources de données en un seul appel réseau avec GraphQL, il n'est pas nécessaire de convertir ou de reconstruire une application REST existante à partir de zéro afin de tirer parti des fonctionnalités en temps réel AWS AppSync de celle-ci. Par exemple, vous pouvez avoir une charge de travail CRUD existante dans un point de terminaison d'API distinct, les clients envoyant et recevant des messages ou des événements de l'application existante à l' pub/sub API générique en temps réel et à pub/sub des fins uniquement. 

# Définition de filtres d'abonnement améliorés dans AWS AppSync
<a name="aws-appsync-real-time-enhanced-filtering"></a>

**Important**  
À WebSockets partir du 13 mars 2025, vous pouvez créer une PubSub API en temps réel alimentée par AWS AppSync Events. Pour plus d'informations, consultez la section [Publier des événements via WebSocket](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) le *Guide du développeur d'AWS AppSync événements*.

Dans AWS AppSync, vous pouvez définir et activer la logique métier pour le filtrage des données sur le backend directement dans les résolveurs d'abonnement à l'API GraphQL en utilisant des filtres prenant en charge des opérateurs logiques supplémentaires. Vous pouvez configurer ces filtres, contrairement aux arguments d'abonnement définis dans la requête d'abonnement du client. Pour plus d'informations sur l'utilisation des arguments d'abonnement, consultez[Utilisation d'arguments d'abonnement](aws-appsync-real-time-data.md#using-subscription-arguments). Pour obtenir la liste des opérateurs, voir[AWS AppSync référence de l'utilitaire du modèle de mappage du résolveur](resolver-util-reference.md).

Aux fins du présent document, nous répartissons le filtrage des données en temps réel dans les catégories suivantes :
+ **Filtrage de base** : filtrage basé sur les arguments définis par le client dans la requête d'abonnement.
+ **Filtrage amélioré** : filtrage basé sur une logique définie de manière centralisée dans le backend du AWS AppSync service.

Les sections suivantes expliquent comment configurer des filtres d'abonnement améliorés et présentent leur utilisation pratique.

## Définition des abonnements dans votre schéma GraphQL
<a name="aws-appsync-real-time-enhanced-filtering-using-subscription-filters"></a>

Pour utiliser des filtres d'abonnement améliorés, vous définissez l'abonnement dans le schéma GraphQL, puis vous définissez le filtre amélioré à l'aide d'une extension de filtrage. Pour illustrer le fonctionnement du filtrage amélioré des abonnements AWS AppSync, utilisez le schéma GraphQL suivant, qui définit une API de système de gestion des tickets, à titre d'exemple :

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

Supposons que vous créiez une source de `NONE` données pour votre API, puis que vous associiez un résolveur à la `createTicket` mutation à l'aide de cette source de données. Vos gestionnaires peuvent ressembler à ceci :

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

**Note**  
Les filtres améliorés sont activés dans le gestionnaire du résolveur GraphQL dans le cadre d'un abonnement donné. Pour plus d'informations, consultez la section [Référence du résolveur](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html).

Pour implémenter le comportement du filtre amélioré, vous devez utiliser la `extensions.setSubscriptionFilter()` fonction pour définir une expression de filtre évaluée par rapport aux données publiées à partir d'une mutation GraphQL susceptible d'intéresser les clients abonnés. Pour plus d'informations sur les extensions de filtrage, consultez la section [Extensions](https://docs.aws.amazon.com//appsync/latest/devguide/extensions-js.html).

La section suivante explique comment utiliser les extensions de filtrage pour implémenter des filtres améliorés.

## Création de filtres d'abonnement améliorés à l'aide d'extensions de filtrage
<a name="aws-appsync-real-time-enhanced-filtering-defining-filters"></a>

Les filtres améliorés sont écrits en JSON dans le gestionnaire de réponses des résolveurs de l'abonnement. Les filtres peuvent être regroupés dans une liste appelée `filterGroup` a. Les filtres sont définis à l'aide d'au moins une règle, chacune comportant des champs, des opérateurs et des valeurs. Définissons un nouveau résolveur pour `onSpecialTicketCreated` configurer un filtre amélioré. Vous pouvez configurer plusieurs règles dans un filtre qui sont évaluées à l'aide de la logique ET, tandis que plusieurs filtres d'un groupe de filtres sont évalués à l'aide de la logique 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;
}
```

Sur la base des filtres définis dans l'exemple précédent, les tickets importants sont automatiquement envoyés aux clients API abonnés si un ticket est créé avec :
+ `priority`niveau `high` ou `medium`

  AND 
+ `severity`niveau supérieur ou égal à `7` (`ge`)

OU 
+ `classification`billet réglé à `Security` 

  AND 
+ `group`assignation définie sur `admin` ou `operators`

![\[Exemple illustrant une requête de filtrage de tickets\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/images/aws-priority-example.png)


Les filtres définis dans le résolveur d'abonnement (filtrage amélioré) ont priorité sur le filtrage basé uniquement sur les arguments d'abonnement (filtrage de base). Pour plus d'informations sur l'utilisation des arguments d'abonnement, consultez la section [Utilisation des arguments d'abonnement](https://docs.aws.amazon.com//appsync/latest/devguide/aws-appsync-real-time-data.html#using-subscription-arguments)).

Si un argument est défini et requis dans le schéma GraphQL de l'abonnement, le filtrage basé sur l'argument donné n'a lieu que si l'argument est défini en tant que règle dans la méthode du résolveur. `extensions.setSubscriptionFilter()` Toutefois, s'il n'existe aucune méthode de `extensions` filtrage dans le résolveur d'abonnement, les arguments définis dans le client ne sont utilisés que pour le filtrage de base. Vous ne pouvez pas utiliser simultanément le filtrage de base et le filtrage amélioré.

Vous pouvez utiliser la [`context`variable](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html) dans la logique d'extension de filtre de l'abonnement pour accéder aux informations contextuelles relatives à la demande. Par exemple, lorsque vous utilisez des groupes d'utilisateurs Amazon Cognito, des autorisateurs personnalisés OIDC ou Lambda pour l'autorisation, vous pouvez récupérer des informations sur vos utilisateurs au `context.identity` moment de l'établissement de l'abonnement. Vous pouvez utiliser ces informations pour établir des filtres en fonction de l'identité de vos utilisateurs.

Supposons maintenant que vous souhaitez implémenter le comportement de filtre amélioré pour`onGroupTicketCreated`. L'`onGroupTicketCreated`abonnement nécessite un `group` nom obligatoire comme argument. Une fois créés, un `pending` statut est automatiquement attribué aux tickets. Vous pouvez configurer un filtre d'abonnement pour ne recevoir que les tickets nouvellement créés appartenant au groupe fourni :

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

Lorsque les données sont publiées à l'aide d'une mutation, comme dans l'exemple suivant :

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

Les clients abonnés écoutent les données à transmettre automatiquement WebSockets dès qu'un ticket est créé avec la `createTicket` mutation :

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

Les clients peuvent être abonnés sans arguments car la logique de filtrage est implémentée dans le AWS AppSync service avec un filtrage amélioré, ce qui simplifie le code client. Les clients reçoivent des données uniquement si les critères de filtre définis sont remplis.

## Définition de filtres améliorés pour les champs de schéma imbriqués
<a name="aws-appsync-real-time-enhanced-filters-nested-schema-fields.title"></a>

Vous pouvez utiliser le filtrage des abonnements amélioré pour filtrer les champs de schéma imbriqués. Supposons que nous ayons modifié le schéma de la section précédente pour inclure les types de localisation et d'adresse :

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

Avec ce schéma, vous pouvez utiliser un `.` séparateur pour représenter l'imbrication. L'exemple suivant ajoute une règle de filtre pour un champ de schéma imbriqué sous`location.address.country`. L'abonnement sera déclenché si l'adresse du ticket est définie comme suit `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;
}
```

Dans l'exemple ci-dessus, `location` représente le niveau d'imbrication un, `address` représente le niveau d'imbrication deux et `country` représente le niveau d'imbrication trois, tous ces éléments étant séparés par le séparateur. `.`

Vous pouvez tester cet abonnement en utilisant la `createTicket` mutation :

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

## Définition de filtres améliorés à partir du client
<a name="aws-appsync-real-time-enhanced-filtering-defining-from-client"></a>

Vous pouvez utiliser le filtrage de base dans GraphQL avec des arguments d'[abonnement](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-data.html#using-subscription-arguments). Le client qui effectue l'appel dans la requête d'abonnement définit les valeurs des arguments. Lorsque des filtres améliorés sont activés dans un résolveur AWS AppSync d'abonnement avec le `extensions` filtrage, les filtres principaux définis dans le résolveur ont la priorité et la priorité.

Configurez des filtres améliorés dynamiques définis par le client à l'aide d'un `filter` argument dans l'abonnement. Lorsque vous configurez ces filtres, vous devez mettre à jour le schéma GraphQL pour refléter le nouvel argument :

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

Le client peut ensuite envoyer une demande d'abonnement comme dans l'exemple suivant :

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

Vous pouvez configurer la variable de requête comme dans l'exemple suivant :

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

L'utilitaire de `util.transform.toSubscriptionFilter()` résolution peut être implémenté dans le modèle de mappage des réponses aux abonnements pour appliquer le filtre défini dans l'argument d'abonnement pour chaque client :

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

Grâce à cette stratégie, les clients peuvent définir leurs propres filtres qui utilisent une logique de filtrage améliorée et des opérateurs supplémentaires. Les filtres sont attribués lorsqu'un client donné invoque la requête d'abonnement via une WebSocket connexion sécurisée. Pour plus d'informations sur l'utilitaire de transformation pour un filtrage amélioré, notamment sur le format de la charge utile de la variable de `filter` requête, consultez la section Présentation des [JavaScriptrésolveurs](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html).

## Restrictions de filtrage améliorées supplémentaires
<a name="aws-appsync-real-time-enhanced-filtering-additional-restrictions"></a>

Vous trouverez ci-dessous plusieurs cas d'utilisation dans lesquels des restrictions supplémentaires sont imposées aux filtres améliorés :
+ Les filtres améliorés ne prennent pas en charge le filtrage pour les listes d'objets de niveau supérieur. Dans ce cas d'utilisation, les données publiées issues de la mutation seront ignorées pour les abonnements améliorés.
+ AWS AppSync prend en charge jusqu'à cinq niveaux de nidification. Les filtres appliqués aux champs de schéma après le niveau d'imbrication 5 seront ignorés. Prenons la réponse GraphQL ci-dessous. L'entrée `continent` sur le terrain `venue.address.country.metadata.continent` est autorisée car il s'agit d'un nid de niveau 5. Cependant, `financial` comme `venue.address.country.metadata.capital.financial` il s'agit d'un nid de niveau 6, le filtre ne fonctionnera pas :

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

# Désinscription de WebSocket connexions à l'aide de filtres dans AWS AppSync
<a name="aws-appsync-real-time-invalidation"></a>

**Important**  
À WebSockets partir du 13 mars 2025, vous pouvez créer une PubSub API en temps réel alimentée par AWS AppSync Events. Pour plus d'informations, consultez la section [Publier des événements via WebSocket](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) le *Guide du développeur d'AWS AppSync événements*.

Dans AWS AppSync, vous pouvez vous désinscrire de force et fermer (invalider) une WebSocket connexion depuis un client connecté en fonction d'une logique de filtrage spécifique. Cela est utile dans les scénarios liés aux autorisations, par exemple lorsque vous supprimez un utilisateur d'un groupe.

L'invalidation de l'abonnement se produit en réponse à une charge utile définie dans une mutation. Nous vous recommandons de traiter les mutations utilisées pour invalider les connexions d'abonnement comme des opérations administratives dans votre API et de définir les autorisations en conséquence en limitant leur utilisation à un utilisateur administrateur, à un groupe ou à un service principal. Par exemple, en utilisant des directives d'autorisation de schéma telles que `@aws_auth(cognito_groups: ["Administrators"])` ou`@aws_iam`. Pour plus d'informations, consultez la section [Utilisation de modes d'autorisation supplémentaires](https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html#using-additional-authorization-modes).

Les filtres d'invalidation utilisent la même syntaxe et la même logique que les [filtres d'abonnement améliorés](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-enhanced-filtering.html). Définissez ces filtres à l'aide des utilitaires suivants :
+ `extensions.invalidateSubscriptions()`— Défini dans le gestionnaire de réponse du résolveur GraphQL pour une mutation.
+ `extensions.setSubscriptionInvalidationFilter()`— Défini dans le gestionnaire de réponses du résolveur GraphQL pour les abonnements liés à la mutation.

Pour plus d'informations sur les extensions de filtrage d'invalidation, consultez la section Présentation [JavaScriptdes résolveurs.](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)

## Utilisation de l'invalidation de l'abonnement
<a name="aws-appsync-real-time-invalidation-using-invalidations"></a>

Pour voir comment fonctionne l'invalidation des abonnements AWS AppSync, utilisez le schéma GraphQL suivant :

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

Définissez un filtre d'invalidation dans le code du résolveur de `removeUserFromGroup` mutations :

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

Lorsque la mutation est invoquée, les données définies dans l'`payload`objet sont utilisées pour annuler l'abonnement défini dans`subscriptionField`. Un filtre d'invalidation est également défini dans le modèle de mappage des réponses de l'`onGroupMessageCreated`abonnement. 

Si la `extensions.invalidateSubscriptions()` charge utile contient un identifiant correspondant à celui IDs du client abonné tel que défini dans le filtre, l'abonnement correspondant est désabonné. De plus, la WebSocket connexion est fermée. Définissez le code de résolution d'abonnement pour l'`onGroupMessageCreated`abonnement :

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

Notez que le gestionnaire de réponse aux abonnements peut avoir des filtres d'abonnement et des filtres d'invalidation définis en même temps.

Supposons,  par exemple, que le client A abonne un nouvel utilisateur avec l'ID `user-1` au groupe ayant l'ID `group-1` en utilisant la demande d'abonnement suivante :

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

AWS AppSync exécute le résolveur d'abonnement, qui génère des filtres d'abonnement et d'invalidation tels que définis dans le modèle de mappage de `onGroupMessageCreated` réponses précédent. Pour le client A, les filtres d'abonnement autorisent l'envoi de données uniquement à`group-1`, et les filtres d'invalidation sont définis pour `user-1` les `group-1` deux.

Supposons maintenant que le client B abonne un utilisateur avec l'ID `user-2` à un groupe avec l'ID `group-2` en utilisant la demande d'abonnement suivante :

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

AWS AppSync exécute le résolveur d'abonnement, qui génère des filtres d'abonnement et d'invalidation. Pour le client B, les filtres d'abonnement autorisent l'envoi de données uniquement à`group-2`, et les filtres d'invalidation sont définis pour les deux `user-2` et`group-2`.

Supposons ensuite qu'un nouveau message de groupe avec l'ID `message-1` soit créé à l'aide d'une demande de mutation, comme dans l'exemple suivant :

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

Les clients abonnés correspondant aux filtres définis reçoivent automatiquement la charge utile de données suivante via WebSockets :

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

Le client A reçoit le message car les critères de filtrage correspondent au filtre d'abonnement défini. Cependant, le client B ne reçoit pas le message, car l'utilisateur n'en fait pas partie`group-1`. De plus, la demande ne correspond pas au filtre d'abonnement défini dans le résolveur d'abonnement.

Enfin, supposons que cela `user-1` soit supprimé `group-1` lors de l'utilisation de la demande de mutation suivante :

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

La mutation initie une invalidation d'abonnement telle que définie dans le code du gestionnaire de réponse du `extensions.invalidateSubscriptions()` résolveur. AWS AppSync désabonne ensuite le client A et ferme sa WebSocket connexion. Le client B n'est pas affecté, car la charge utile d'invalidation définie dans la mutation ne correspond pas à son utilisateur ou à son groupe.

Lorsqu'une connexion est AWS AppSync invalidée, le client reçoit un message confirmant qu'il est désabonné :

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

## Utilisation de variables contextuelles dans les filtres d'invalidation des abonnements
<a name="aws-appsync-real-time-invalidation-context"></a>

Comme pour les filtres d'abonnement améliorés, vous pouvez utiliser la [`context`variable](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html) de l'extension du filtre d'invalidation d'abonnement pour accéder à certaines données.

Par exemple, il est possible de configurer une adresse e-mail comme charge utile d'invalidation lors de la mutation, puis de l'associer à l'attribut e-mail ou à la réclamation d'un utilisateur abonné autorisé par les groupes d'utilisateurs Amazon Cognito ou OpenID Connect. Le filtre d'invalidation défini dans l'invalidateur `extensions.setSubscriptionInvalidationFilter()` d'abonnement vérifie si l'adresse e-mail définie par la `extensions.invalidateSubscriptions()` charge utile de la mutation correspond à l'adresse e-mail récupérée à partir du jeton JWT de l'utilisateur, déclenchant ainsi l'invalidation. `context.identity.claims.email`

# Création d'un WebSocket client en temps réel dans AWS AppSync
<a name="real-time-websocket-client"></a>

**Important**  
À WebSockets partir du 13 mars 2025, vous pouvez créer une PubSub API en temps réel alimentée par AWS AppSync Events. Pour plus d'informations, consultez la section [Publier des événements via WebSocket](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) le *Guide du développeur d'AWS AppSync événements*.

AWS AppSyncLe WebSocket client en temps réel permet les abonnements GraphQL via un processus en plusieurs étapes. Le client établit d'abord une WebSocket connexion avec le point de terminaison AWS AppSync en temps réel, envoie un message d'initialisation de la connexion et attend un accusé de réception. Une fois la connexion établie, le client enregistre les abonnements en envoyant des messages de démarrage contenant des requêtes GraphQL uniques IDs . AWS AppSync confirme les abonnements réussis par des messages d'accusé de réception. Le client écoute ensuite les événements d'abonnement, qui sont déclenchés par les mutations correspondantes. Pour maintenir la connexion, AWS AppSync envoie régulièrement des messages de maintien en vie. Lorsque vous avez terminé, le client annule l'enregistrement des abonnements en envoyant des messages d'arrêt. Ce système prend en charge plusieurs abonnements sur une seule WebSocket connexion et prend en charge différents modes d'autorisation, notamment les clés API, les groupes d'utilisateurs Amazon Cognito, IAM et Lambda.

## WebSocket Implémentation du client en temps réel pour les abonnements GraphQL
<a name="appsynclong-real-time-websocket-client-implementation-guide-for-graphql-subscriptions"></a>

Le schéma de séquence et les étapes suivants montrent le flux de travail des abonnements en temps réel entre le WebSocket client, le client HTTP et AWS AppSync.

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


1. Le client établit une WebSocket connexion avec le point de terminaison AWS AppSync en temps réel. En cas d’erreur réseau, le client doit effectuer une interruption exponentielle instable. Pour plus d'informations, consultez la section [Exponential Backoff and jitter](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/) sur le AWS blog d'architecture.

1. (Facultatif) Une fois la WebSocket connexion établie, le client envoie un `connection_init` message.

1. S'`connection_init`il est envoyé, le client attend un `connection_ack` message de AWS AppSync. Ce message inclut un `connectionTimeoutMs` paramètre, qui est le temps d'attente maximal en millisecondes pour un message `"ka"` (keep-alive).

1. AWS AppSync envoie `"ka"` des messages périodiquement. Le client enregistre l'heure à laquelle il a reçu chaque `"ka"` message. Si le client ne reçoit aucun `"ka"` message dans les `connectionTimeoutMs` millisecondes, il doit fermer la connexion.

1. Le client enregistre l'abonnement en envoyant un message d'abonnement `start`. Une seule WebSocket connexion prend en charge plusieurs abonnements, même s'ils utilisent des modes d'autorisation différents.

1. Le client attend d'envoyer des `start_ack` messages AWS AppSync pour confirmer les abonnements réussis. En cas d'erreur, AWS AppSync renvoie un `"type": "error"` message.

1. Le client écoute les événements d'abonnement, qui sont envoyés après l'appel d'une mutation correspondante. Les requêtes et les mutations sont généralement envoyées au point `https://` de terminaison AWS AppSync GraphQL. Les abonnements passent par le point de terminaison AWS AppSync en temps réel à l'aide du WebSocket protocole secure (`wss://`).

1. Le client annule l'abonnement en envoyant un message d'abonnement `stop`.

1. Après avoir annulé tous les abonnements et vérifié qu'aucun message n'est transféré via le WebSocket, le client peut se déconnecter de la WebSocket connexion.

## Détails de la poignée de main pour établir la connexion WebSocket
<a name="handshake-details-to-establish-the-websocket-connection"></a>

Pour établir une connexion et initier une poignée de main réussie avec AWS AppSync, un WebSocket client a besoin des éléments suivants :
+ Le point final AWS AppSync en temps réel
+ En-têtes : contiennent des informations relatives au point de AWS AppSync terminaison et à l'autorisation. AWS AppSync prend en charge les trois méthodes suivantes pour fournir des en-têtes : 
  + En-têtes via une chaîne de requête
    + Les informations d'en-tête sont codées sous forme de chaîne base64, dérivée d'un objet JSON stringifié. Cet objet JSON contient des informations relatives au AWS AppSync point de terminaison et à l'autorisation. Le contenu de l'objet JSON varie en fonction du mode d'autorisation.
  + En-têtes via `Sec-WebSocket-Protocol`
    + Une chaîne codée en Base64URL provenant de l'objet JSON sous forme de chaîne contenant des informations relatives au point de AWS AppSync terminaison et à l'autorisation est transmise en tant que protocole dans l'en-tête. `Sec-WebSocket-Protocol` Le contenu de l'objet JSON varie en fonction du mode d'autorisation.
  + En-têtes via des en-têtes HTTP standard :
    + Les en-têtes peuvent être transmis en tant qu'en-têtes HTTP standard dans la demande de connexion, de la même manière que les en-têtes sont transmis pour les requêtes GraphQL et les mutations. AWS AppSync Toutefois, le transfert d'en-têtes via des en-têtes HTTP standard n'est pas pris en charge pour les demandes de connexion API privées.
+  `payload`— Chaîne codée en Base64 de. `payload` La charge utile n'est nécessaire que si les en-têtes sont fournis à l'aide d'une chaîne de requête

Avec ces exigences, un WebSocket client peut se connecter à l'URL, qui contient le point de terminaison en temps réel avec la chaîne de requête, en utilisant `graphql-ws` comme WebSocket protocole.

### Découverte du point de terminaison en temps réel à partir du point de terminaison GraphQL
<a name="discovering-the-appsync-real-time-endpoint-from-the-appsync-graphql-endpoint"></a>

Le point de terminaison AWS AppSync GraphQL et le point de terminaison AWS AppSync en temps réel sont légèrement différents en termes de protocole et de domaine. Vous pouvez récupérer le point de terminaison GraphQL à l'aide de la commande AWS Command Line Interface (AWS CLI). `aws appsync get-graphql-api`

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

****AWS AppSync point final en temps réel :****  
 `wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql`

Les applications peuvent se connecter au point de terminaison AWS AppSync GraphQL (`https://`) à l'aide de n'importe quel client HTTP pour les requêtes et les mutations. Les applications peuvent se connecter au point de terminaison AWS AppSync en temps réel (`wss://`) en utilisant n'importe quel WebSocket client pour les abonnements.

Avec les noms de domaine personnalisés, vous pouvez interagir avec les deux points de terminaison en utilisant un seul domaine. Par exemple, si vous le configurez `api.example.com` en tant que domaine personnalisé, vous pouvez interagir avec votre GraphQL et vos points de terminaison en temps réel à l'aide des éléments suivants : URLs

**AWS AppSync point de terminaison GraphQL de domaine personnalisé :**  
`https://api.example.com/graphql`

**AWS AppSync point de terminaison en temps réel de domaine personnalisé :**  
`wss://api.example.com/graphql/realtime`

## Format des paramètres d'en-tête basé sur le mode d'autorisation de l' AWS AppSync API
<a name="header-parameter-format-based-on-appsync-api-authorization-mode"></a>

Le format de l'`header`objet utilisé dans la chaîne de requête de connexion varie en fonction du mode d'autorisation de l' AWS AppSync API. Le `host` champ de l'objet fait référence au point de terminaison AWS AppSync GraphQL, qui est utilisé pour valider la connexion même si l'`wss://`appel est effectué par rapport au point de terminaison en temps réel. Pour initier la poignée de main et établir la connexion autorisée, `payload` doit être un objet JSON vide. La charge utile n'est nécessaire que si les en-têtes sont transmis via une chaîne de requête.

Les sections suivantes présentent les formats d'en-tête pour chaque mode d'autorisation.

### Clé API
<a name="api-key"></a>

#### En-tête de clé API
<a name="api-key-list"></a>

**Contenu de l'en-tête**
+  `"host": <string>`: L'hôte du point de terminaison AWS AppSync GraphQL ou votre nom de domaine personnalisé.
+  `"x-api-key": <string>`: clé d'API configurée pour l' AWS AppSync API.

**Exemple**

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

**En-têtes via une chaîne de requête**

Tout d'abord, un objet JSON contenant le `host` et `x-api-key` est converti en chaîne. Ensuite, cette chaîne est codée en utilisant le codage base64. La chaîne codée en base64 qui en résulte est ajoutée en tant que paramètre de requête nommé `header` à l' WebSocketURL pour établir la connexion avec le point de terminaison AWS AppSync en temps réel. L'URL de demande qui en résulte prend la forme suivante :

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

Il est important de noter qu'en plus de l'objet d'en-tête codé en base64, un objet JSON vide \$1\$1 est également codé en base64 et inclus en tant que paramètre de requête distinct nommé `payload` dans l'URL. WebSocket

**En-têtes via `Sec-WebSocket-Protocol`**

Un objet JSON contenant le `host` et `x-api-key` est converti en chaîne puis codé à l'aide du codage Base64URL. La chaîne codée en Base64URL qui en résulte est préfixée par. `header-` Cette chaîne préfixée est ensuite utilisée comme nouveau sous-protocole en plus de figurer dans l'`Sec-WebSocket-Protocol`en-tête lors de `graphql-ws` l'établissement de la WebSocket connexion avec le point de terminaison AWS AppSync en temps réel. 

L'URL de demande qui en résulte prend la forme suivante :

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

L'`Sec-WebSocket-Protocol`en-tête contient la valeur suivante :

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

**En-têtes via des en-têtes HTTP standard**

Dans cette méthode, les informations relatives à l'hôte et à la clé d'API sont transmises à l'aide d'en-têtes HTTP standard lors de l'établissement de la WebSocket connexion avec le point de terminaison AWS AppSync en temps réel. L'URL de demande qui en résulte prend la forme suivante :

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

Les en-têtes de demande incluraient les éléments suivants :

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

### Groupes d'utilisateurs Amazon Cognito et OpenID Connect (OIDC)
<a name="amazon-cognito-user-pools-and-openid-connect-oidc"></a>

#### Amazon Cognito et en-tête OIDC
<a name="amazon-cognito-user-pools-and-openid-connect-oidc-list"></a>

Contenu de l'en-tête :
+  `"Authorization": <string>`: un jeton d'identification JWT. L'en-tête peut utiliser un [schéma Bearer](https://datatracker.ietf.org/doc/html/rfc6750#section-2.1).
+  `"host": <string>`: L'hôte du point de terminaison AWS AppSync GraphQL ou votre nom de domaine personnalisé.

Exemple :

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

**En-têtes via une chaîne de requête**

Tout d'abord, un objet JSON contenant le `host` et `Authorization` est converti en chaîne. Ensuite, cette chaîne est codée en utilisant le codage base64. La chaîne codée en base64 qui en résulte est ajoutée en tant que paramètre de requête nommé `header` à l' WebSocket URL pour établir la connexion avec le point de terminaison AWS AppSync en temps réel. L'URL de demande qui en résulte prend la forme suivante :

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

Il est important de noter qu'en plus de l'objet d'en-tête codé en base64, un objet JSON vide \$1\$1 est également codé en base64 et inclus en tant que paramètre de requête distinct nommé `payload` dans l'URL. WebSocket

**En-têtes via `Sec-WebSocket-Protocol`**

Un objet JSON contenant le `host` et `Authorization` est converti en chaîne puis codé à l'aide du codage Base64URL. La chaîne codée en Base64URL qui en résulte est préfixée par. `header-` Cette chaîne préfixée est ensuite utilisée comme nouveau sous-protocole en plus de figurer dans l'`Sec-WebSocket-Protocol`en-tête lors de `graphql-ws` l'établissement de la WebSocket connexion avec le point de terminaison AWS AppSync en temps réel. 

L'URL de demande qui en résulte prend la forme suivante :

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

L'`Sec-WebSocket-Protocol`en-tête contient la valeur suivante :

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

**En-têtes via des en-têtes HTTP standard**

Dans cette méthode, les informations d'hôte et d'autorisation sont transmises à l'aide d'en-têtes HTTP standard lors de l'établissement de la WebSocket connexion avec le point de terminaison AWS AppSync en temps réel. L'URL de demande qui en résulte prend la forme suivante :

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

Les en-têtes de demande incluraient les éléments suivants :

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

#### En-tête IAM
<a name="iam-list"></a>

**Contenu de l'en-tête**
+  `"accept": "application/json, text/javascript"` : un paramètre `<string>` constant.
+  `"content-encoding": "amz-1.0"` : un paramètre `<string>` constant.
+  `"content-type": "application/json; charset=UTF-8"` : un paramètre `<string>` constant.
+  `"host": <string>`: Il s'agit de l'hôte du point de terminaison AWS AppSync GraphQL.
  + `"x-amz-date": <string>`: L'horodatage doit être en UTC et au format ISO 8601 suivant : YYYYMMDD'T'HHMMSS'Z'. Par exemple, 20150830T123600Z est un horodatage valide. N'incluez pas de millisecondes dans l'horodatage. Pour plus d'informations, consultez la section [Gestion des dates dans la version 4 de Signature](https://docs.aws.amazon.com/general/latest/gr/sigv4-date-handling.html) dans le *Références générales AWS*.
  +  `"X-Amz-Security-Token": <string>`: le jeton de AWS session, qui est requis lors de l'utilisation d'informations d'identification de sécurité temporaires. Pour plus d'informations, consultez [Utilisation d'informations d'identification temporaires avec des ressources AWS](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_credentials_temp_use-resources.html) dans le *Guide de l'utilisateur IAM*.
  +  `"Authorization": <string>`: informations de signature de la version 4 (SigV4) pour le AWS AppSync point de terminaison. Pour plus d'informations sur le processus de signature, voir [Tâche 4 : ajouter la signature à la requête HTTP](https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html) dans le *Références générales AWS*.

La requête HTTP de signature SigV4 inclut une URL canonique, qui est le point de terminaison GraphQL AWS AppSync auquel `/connect` est ajouté. La AWS région du point de terminaison du service est la même région que celle dans laquelle vous utilisez l' AWS AppSync API, et le nom du service est « appsync ». La requête HTTP pour la signature est la suivante :

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

**Exemple**

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

**En-têtes via une chaîne de requête**

Tout d'abord, un objet JSON contenant le `host` (point de terminaison AWS AppSync GraphQL) et les autres en-têtes d'autorisation est converti en chaîne. Ensuite, cette chaîne est codée en utilisant le codage base64. La chaîne codée en base64 qui en résulte est ajoutée à l' WebSocket URL en tant que paramètre de requête nommé. `header` L'URL de demande qui en résulte prend la forme suivante :

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

Il est important de noter qu'en plus de l'objet d'en-tête codé en base64, un objet JSON vide \$1\$1 est également codé en base64 et inclus en tant que paramètre de requête distinct nommé `payload` dans l'URL. WebSocket

**En-têtes via `Sec-WebSocket-Protocol`**

Un objet JSON contenant les en-têtes d'autorisation `host` et les autres est converti en chaîne puis codé à l'aide du codage Base64URL. La chaîne codée en Base64URL qui en résulte est préfixée par. `header-` Cette chaîne préfixée est ensuite utilisée comme nouveau sous-protocole en plus de figurer dans l'`Sec-WebSocket-Protocol`en-tête lors de `graphql-ws` l'établissement de la WebSocket connexion avec le point de terminaison AWS AppSync en temps réel. 

L'URL de demande qui en résulte prend la forme suivante :

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

L'`Sec-WebSocket-Protocol`en-tête contient la valeur suivante :

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

**En-têtes via des en-têtes HTTP standard**

Dans cette méthode, l'hôte et les autres informations d'autorisation sont transmises à l'aide d'en-têtes HTTP standard lors de l'établissement de la WebSocket connexion avec le point de terminaison AWS AppSync en temps réel. L'URL de demande qui en résulte prend la forme suivante :

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

Les en-têtes de demande incluraient les éléments suivants :

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

Pour signer la demande à l'aide d'un domaine personnalisé, procédez comme suit :

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

**Exemple**

```
{
  "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 demande avec chaîne de requête**

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

**Note**  
Une WebSocket connexion peut comporter plusieurs abonnements (même avec différents modes d'authentification). Une façon de mettre cela en œuvre consiste à créer une WebSocket connexion pour le premier abonnement, puis à la fermer lorsque le dernier abonnement n'est pas enregistré. Vous pouvez optimiser cela en attendant quelques secondes avant de fermer la WebSocket connexion, au cas où l'application serait abonnée immédiatement après le désenregistrement du dernier abonnement. Pour une application mobile, par exemple, lorsque vous passez d'un écran à un autre, lors du *démontage*, elle arrête un abonnement, et lors du *montage de* l'événement, elle lance un autre abonnement.

### Autorisation Lambda
<a name="lambda-auth"></a>

#### En-tête d'autorisation Lambda
<a name="lambda-auth-list"></a>

**Contenu de l'en-tête**
+  `"Authorization": <string>`: valeur transmise en tant que`authorizationToken`.
+  `"host": <string>`: L'hôte du point de terminaison AWS AppSync GraphQL ou votre nom de domaine personnalisé.

**Exemple**

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

**En-têtes via une chaîne de requête**

Tout d'abord, un objet JSON contenant le `host` et `Authorization` est converti en chaîne. Ensuite, cette chaîne est codée en utilisant le codage base64. La chaîne codée en base64 qui en résulte est ajoutée en tant que paramètre de requête nommé `header` à l' WebSocket URL pour établir la connexion avec le point de terminaison AWS AppSync en temps réel. L'URL de demande qui en résulte prend la forme suivante :

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

Il est important de noter qu'en plus de l'objet d'en-tête codé en base64, un objet JSON vide \$1\$1 est également codé en base64 et inclus en tant que paramètre de requête distinct nommé `payload` dans l'URL. WebSocket

**En-têtes via `Sec-WebSocket-Protocol`**

Un objet JSON contenant le `host` et `Authorization` est converti en chaîne puis codé à l'aide du codage Base64URL. La chaîne codée en Base64URL qui en résulte est préfixée par. `header-` Cette chaîne préfixée est ensuite utilisée comme nouveau sous-protocole en plus de figurer dans l'`Sec-WebSocket-Protocol`en-tête lors de `graphql-ws` l'établissement de la WebSocket connexion avec le point de terminaison AWS AppSync en temps réel. 

L'URL de demande qui en résulte prend la forme suivante :

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

L'`Sec-WebSocket-Protocol`en-tête contient la valeur suivante :

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

**En-têtes via des en-têtes HTTP standard**

Dans cette méthode, les informations d'hôte et d'autorisation sont transmises à l'aide d'en-têtes HTTP standard lors de l'établissement de la WebSocket connexion avec le point de terminaison AWS AppSync en temps réel. L'URL de demande qui en résulte prend la forme suivante :

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

Les en-têtes de demande incluraient les éléments suivants :

```
"sec-websocket-protocol" : ["graphql-ws"]
"Authorization":"eyEXAMPLEiJjbG5xb3A5eW5MK09QYXIrMTJHWEFLSXBieU5WNHhsQjEXAMPLEnM2WldvPSIsImFsZyI6IlEXAMPLEn0.eyEXAMPLEiJhNmNmMjcwNy0xNjgxLTQ1NDItOWYxOC1lNjY0MTg2NjlkMzYiLCJldmVudF9pZCI6ImVkMzM5MmNkLWNjYTMtNGM2OC1hNDYyLTJlZGI3ZTNmY2FjZiIsInRva2VuX3VzZSI6ImFjY2VzcyIsInNjb3BlIjoiYXdzLmNvZ25pdG8uc2lnbmluLnVzZXIuYWRtaW4iLCJhdXRoX3RpbWUiOjE1Njk0NTc3MTgsImlzcyI6Imh0dHBzOlwvXC9jb2duaXRvLWlkcC5hcC1zb3V0aGVhc3QtMi5hbWF6b25hd3MuY29tXC9hcC1zb3V0aGVhc3QtMl83OHY0SVZibVAiLCJleHAiOjE1Njk0NjEzMjAsImlhdCI6MTU2OTQ1NzcyMCwianRpIjoiNTgzZjhmYmMtMzk2MS00YzA4LWJhZTAtYzQyY2IxMTM5NDY5IiwiY2xpZW50X2lkIjoiM3FlajVlMXZmMzd1N3RoZWw0dG91dDJkMWwiLCJ1c2VybmFtZSI6ImVsb3EXAMPLEn0.B4EXAMPLEFNpJ6ikVp7e6DRee95V6Qi-zEE2DJH7sHOl2zxYi7f-SmEGoh2AD8emxQRYajByz-rE4Jh0QOymN2Ys-ZIkMpVBTPgu-TMWDyOHhDUmUj2OP82yeZ3wlZAtr_gM4LzjXUXmI_K2yGjuXfXTaa1mvQEBG0mQfVd7SfwXB-jcv4RYVi6j25qgow9Ew52ufurPqaK-3WAKG32KpV8J4-Wejq8t0c-yA7sb8EnB551b7TU93uKRiVVK3E55Nk5ADPoam_WYE45i3s5qVAP_-InW75NUoOCGTsS8YWMfb6ecHYJ-1j-bzA27zaT9VjctXn9byNFZmEXAMPLExw",
"host":"example1234567890000.appsync-api.us-east-1.amazonaws.com"
```

## WebSocket Fonctionnement en temps réel
<a name="real-time-websocket-operation"></a>

Après avoir initié une WebSocket poignée de main réussie avec AWS AppSync, le client doit envoyer un message suivant pour se connecter AWS AppSync pour différentes opérations. Ces messages nécessitent les données suivantes :
+  `type` : type de l'opération.
+  `id`: identifiant unique pour l'abonnement. Nous vous recommandons d'utiliser un UUID à cet effet.
+  `payload`: charge utile associée, en fonction du type d'opération.

Le `type` champ est le seul champ obligatoire ; les `payload` champs `id` et sont facultatifs.

### Séquence des événements
<a name="sequence-of-events"></a>

Pour lancer, établir, enregistrer et traiter correctement la demande d'abonnement, le client doit suivre la séquence suivante :

1. Initialisation de la connexion (`connection_init`)

1. Accusé de réception de connexion (`connection_ack`)

1. Inscription à l'abonnement (`start`)

1. Accusé de réception d'abonnement (`start_ack`)

1. Traitement de l'abonnement (`data`)

1. Annulation de l'abonnement (`stop`)

## Message d'initiation de connexion
<a name="connection-init-message"></a>

(Facultatif) Après une poignée de main réussie, le client peut envoyer le `connection_init` message pour commencer à communiquer avec le point de terminaison AWS AppSync en temps réel. Le message est une chaîne obtenue en chaînant l'objet JSON comme suit :

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

## Message d'accusé de réception de connexion
<a name="connection-acknowledge-message"></a>

Après avoir envoyé le message `connection_init`, le client doit attendre le message `connection_ack`. Tous les messages envoyés avant réception `connection_ack` sont ignorés. Le message doit se lire comme suit :

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

## Message « keep-alive »
<a name="keep-alive-message"></a>

Outre le message d'accusé de réception de connexion, le client reçoit régulièrement des messages de maintien en vie. Si le client ne reçoit pas de message de maintien en vie pendant le délai d'expiration de la connexion, il doit fermer la connexion. AWS AppSync continue d'envoyer ces messages et de gérer les abonnements enregistrés jusqu'à ce que la connexion soit automatiquement interrompue (après 24 heures). Les messages Keep-Alive sont des battements de cœur et le client n'a pas besoin d'en accuser réception.

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

## Message d'inscription à l'abonnement
<a name="subscription-registration-message"></a>

Une fois que le client a reçu un `connection_ack` message, il peut envoyer des messages d'enregistrement d'abonnement à AWS AppSync. Ce type de message est un objet JSON sous forme de chaîne qui contient les champs suivants :
+  `"id": <string>`: ID de l'abonnement. Cet identifiant doit être unique pour chaque abonnement, sinon le serveur renvoie une erreur indiquant que l'identifiant d'abonnement est dupliqué.
+  `"type": "start"` : un paramètre `<string>` constant.
+  `"payload": <Object>`: un objet qui contient les informations relatives à l'abonnement.
  +  `"data": <string>`: objet JSON stringifié qui contient une requête GraphQL et des variables.
    +  `"query": <string>`: une opération GraphQL.
    +  `"variables": <Object>`: objet contenant les variables de la requête.
  +  `"extensions": <Object>`: objet contenant un objet d'autorisation.
+  `"authorization": <Object>`: un objet qui contient les champs requis pour l'autorisation.

### Objet d'autorisation pour l'enregistrement de l'abonnement
<a name="authorization-object-for-subscription-registration"></a>

Les mêmes règles de la [Format des paramètres d'en-tête basé sur le mode d'autorisation de l' AWS AppSync API](#header-parameter-format-based-on-appsync-api-authorization-mode) section s'appliquent à l'objet d'autorisation. La seule exception concerne l'IAM, où les informations de signature SigV4 sont légèrement différentes. Pour plus de détails, consultez l'exemple IAM.

Exemple d'utilisation de groupes d'utilisateurs 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"
}
```

Exemple d'utilisation d'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"
}
```

Exemple d'utilisation d'un nom de domaine personnalisé :

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

Il n'est pas nécessaire d'ajouter la signature SigV4 `/connect` à l'URL, et l'opération GraphQL en chaîne JSON la remplace. `data` Voici un exemple de demande de signature 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",
  }
}
```

## Message d'accusé de réception de l'abonnement
<a name="subscription-acknowledge-message"></a>

Après avoir envoyé le message de début d'abonnement, le client doit attendre AWS AppSync d'envoyer le `start_ack` message. Le `start_ack` message indique que l'abonnement est réussi.

Exemple de confirmation d'abonnement :

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

## Message d’erreur
<a name="error-message"></a>

Si l'initialisation de la connexion ou l'enregistrement de l'abonnement échoue, ou si un abonnement est résilié depuis le serveur, le serveur envoie un message d'erreur au client. Si l'erreur se produit au moment de l'initialisation de la connexion, celle-ci sera fermée par le serveur.
+  `"type": "error"` : un paramètre `<string>` constant.
+  `"id": <string>`: L'identifiant de l'abonnement enregistré correspondant, le cas échéant.
+  `"payload" <Object>`: objet contenant les informations d'erreur correspondantes.

Exemple :

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

## Traitement des messages de données
<a name="processing-data-messages"></a>

Lorsqu'un client soumet une mutation, AWS AppSync identifie tous les abonnés intéressés et envoie un `"type":"data"` message à chacun en utilisant l'abonnement `id` correspondant à l'opération `"start"` d'abonnement. Le client est censé suivre l'abonnement `id` qu'il envoie afin que, lorsqu'il reçoit un message de données, il puisse le faire correspondre à l'abonnement correspondant.
+  `"type": "data"` : un paramètre `<string>` constant.
+  `"id": <string>`: ID de l'abonnement enregistré correspondant.
+  `"payload" <Object>`: objet contenant les informations d'abonnement.

Exemple :

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

## Message de désinscription de l'abonnement
<a name="subscription-unregistration-message"></a>

Lorsque l'application souhaite arrêter d'écouter les événements d'abonnement, le client doit envoyer un message contenant l'objet JSON sous forme de chaîne suivant :
+  `"type": "stop"` : un paramètre `<string>` constant.
+  `"id": <string>`: ID de l'abonnement dont vous souhaitez annuler l'enregistrement.

Exemple :

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

AWS AppSync renvoie un message de confirmation avec l'objet JSON stringifié suivant :
+  `"type": "complete"` : un paramètre `<string>` constant.
+  `"id": <string>`: ID de l'abonnement non enregistré.

Une fois que le client a reçu le message de confirmation, il ne reçoit plus aucun message pour cet abonnement en particulier.

Exemple :

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

## Déconnexion du WebSocket
<a name="disconnecting-the-websocket"></a>

Avant de se déconnecter, afin d'éviter toute perte de données, le client doit disposer de la logique nécessaire pour vérifier qu'aucune opération n'est actuellement en cours via la WebSocket connexion. Tous les abonnements doivent être annulés avant de se déconnecter du. WebSocket