

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Verwendung von Abonnements für Echtzeit-Datenanwendungen in AWS AppSync
<a name="aws-appsync-real-time-data"></a>

**Wichtig**  
Ab dem 13. März 2025 können Sie WebSockets mithilfe von AWS AppSync Events eine PubSub Echtzeit-API erstellen. Weitere Informationen finden Sie unter [Ereignisse veröffentlichen über WebSocket](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) im *AWS AppSync Events Developer Guide*.

AWS AppSyncermöglicht es Ihnen, Abonnements zu nutzen, um Live-Anwendungsupdates, Push-Benachrichtigungen usw. zu implementieren. Wenn Clients die GraphQL-Abonnementvorgänge aufrufen, wird automatisch eine sichere WebSocket Verbindung hergestellt und aufrechterhalten von. AWS AppSync Anwendungen können dann Daten in Echtzeit von einer Datenquelle an Abonnenten verteilen und gleichzeitig die Verbindungs- und Skalierungsanforderungen der Anwendung AWS AppSync kontinuierlich verwalten. In den folgenden Abschnitten erfahren Sie, wie Abonnements AWS AppSync funktionieren.

## GraphQL-Schemaabonnementanweisungen
<a name="graphql-schema-subscription-directives"></a>

Abonnements in AWS AppSync werden als Reaktion auf eine Mutation aufgerufen. Das bedeutet, dass Sie jede Datenquelle in AWS AppSync Echtzeit erstellen können, indem Sie eine GraphQL-Schemadirektive für eine Mutation angeben.

Die AWS Amplify Clientbibliotheken kümmern sich automatisch um die Verwaltung der Abonnementverbindungen. Die Bibliotheken verwenden Pure WebSockets als Netzwerkprotokoll zwischen dem Client und dem Dienst.

**Anmerkung**  
Um die Autorisierung bei der Verbindung mit einem Abonnement zu steuern, können Sie AWS Identity and Access Management (IAM), AWS Lambda Amazon Cognito Cognito-Identitätspools oder Amazon Cognito Cognito-Benutzerpools für die Autorisierung auf Feldebene verwenden. Für detaillierte Zugriffskontrollen für Abonnements können Sie Resolver an Ihre Abonnementfelder anhängen und anhand der Identität des Anrufers und der Datenquellen eine Logik ausführen. AWS AppSync Weitere Informationen finden Sie unter [Konfiguration von Autorisierung und Authentifizierung zur Sicherung Ihres GraphQL APIs](security-authz.md).

Abonnements werden durch Mutationen ausgelöst und die Mutationsauswahlmenge wird an Abonnenten gesendet.

Das folgende Beispiel zeigt, wie Sie mit GraphQL-Abonnements arbeiten. Es gibt keine Datenquelle an, da es sich bei der Datenquelle um Lambda, Amazon DynamoDB oder Amazon Service handeln könnte. OpenSearch 

Um mit Abonnements zu beginnen, müssen Sie Ihrem Schema wie folgt einen Abonnement-Einstiegspunkt hinzufügen:

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

Angenommen, Sie haben eine Blog-Website und möchten neue Blogs sowie Änderungen an vorhandenen Blogs abonnieren. Fügen Sie zu diesem Zweck folgende `Subscription`-Definition dem Schema hinzu:

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

Nehmen wir außerdem an, Sie haben die folgenden Mutationen:

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

Sie können diese Felder in Echtzeitfelder umwandeln, indem Sie folgendermaßen eine `@aws_subscribe(mutations: ["mutation_field_1", "mutation_field_2"])`-Richtlinie für jedes Abonnement hinzufügen, für das Sie Benachrichtigungen erhalten möchten:

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

Da das eine Reihe von Mutationseingaben `@aws_subscribe(mutations: ["",..,""])` benötigt, können Sie mehrere Mutationen angeben, wodurch ein Abonnement initiiert wird. Wenn Sie das Abonnement von einem Client aus initiieren, sieht Ihre GraphQL-Abfrage möglicherweise wie folgt aus:

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

Diese Abonnementabfrage wird für Client-Verbindungen und Tools benötigt.

Beim reinen WebSockets Client erfolgt die Filterung der Auswahlsätze pro Client, da jeder Client seinen eigenen Auswahlsatz definieren kann. In diesem Fall muss der Abonnementauswahlsatz eine Teilmenge des Mutationsauswahlsatzes sein. Beispiel: Abonnement `addPost(...){id author title url version}`, das mit Mutation `addedPost{author title}` verknüpft ist, erhält nur den Autor und den Titel des Beitrags. Die anderen Felder werden nicht empfangen. Wenn der Mutation jedoch der Autor in ihrem Auswahlsatz fehlte, erhält der Abonnent einen `null`-Wert für das Autorenfeld (oder einen Fehler, falls das Autorenfeld im Schema als erforderlich/nicht NULL definiert ist).

Der Abonnement-Auswahlsatz ist bei der Verwendung von Pure unerlässlich WebSockets. Wenn ein Feld im Abonnement nicht explizit definiert ist, wird AWS AppSync das Feld nicht zurückgegeben.

Im vorherigen Beispiel hatten die Abonnements keine Argumente. Angenommen, Ihr Schema sieht wie folgt aus:

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

In diesem Fall definiert der Client ein Abonnement wie folgt:

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

Der Rückgabetyp eines `subscription`-Felds in Ihrem Schema muss dem Rückgabetyp des zugehörigen Mutationsfelds entsprechen. Im vorherigen Beispiel war dies als `addPost` und `addedPost` dargestellt, zurückgegeben als `Post`-Typ.

Informationen zum Einrichten von Abonnements auf dem Client finden Sie unter[Erstellen einer Client-Anwendung mit dem Amplify-Client](building-a-client-app.md).

## Abonnementargumente verwenden
<a name="using-subscription-arguments"></a>

Ein wichtiger Teil der Verwendung von GraphQL-Abonnements besteht darin, zu verstehen, wann und wie Argumente verwendet werden. Sie können subtile Änderungen vornehmen, um zu ändern, wie und wann Clients über aufgetretene Mutationen informiert werden sollen. Sehen Sie sich dazu das Beispielschema aus dem Schnellstart-Kapitel an, in dem „Todos“ erstellt wird. Für dieses Beispielschema sind die folgenden Mutationen definiert:

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

Im Standardbeispiel können Clients Updates für alle abonnieren, `Todo` indem sie das `onUpdateTodo` `subscription` ohne Argumente verwenden:

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

Sie können Ihre `subscription` anhand ihrer Argumente filtern. Um beispielsweise nur eine auszulösen, `subscription` wenn eine `todo` mit einem bestimmten aktualisiert `ID` wird, geben Sie den folgenden `ID` Wert an:

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

Sie können auch mehrere Argumente übergeben. Im Folgenden wird beispielsweise gezeigt, `subscription` wie Sie über `Todo` Aktualisierungen an einem bestimmten Ort und zu einer bestimmten Zeit benachrichtigt werden können:

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

Beachten Sie, dass alle Argumente optional sind. Wenn Sie in Ihrem keine Argumente angeben`subscription`, abonnieren Sie alle `Todo` Updates, die in Ihrer Anwendung auftreten. Sie könnten jedoch Ihre Felddefinition aktualisieren, sodass das `ID` Argument erforderlich `subscription` ist. Dies würde die Antwort eines bestimmten `todo` statt aller `todo` s erzwingen:

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

### Argument-Null-Wert hat Bedeutung
<a name="argument-null-value-has-meaning"></a>

Bei einer Abonnementabfrage filtert ein `null` Argumentwert die Ergebnisse anders AWS AppSync, als wenn das Argument vollständig weggelassen wird.

Kehren wir zum Todos-API-Beispiel zurück, in dem wir Todos erstellen könnten. Sehen Sie sich das Beispielschema aus dem Schnellstart-Kapitel an.

Lassen Sie uns unser Schema so ändern, dass es ein neues `owner` Feld für den `Todo` Typ enthält, das beschreibt, wer der Eigentümer ist. Das `owner` Feld ist nicht erforderlich und kann nur aktiviert werden`UpdateTodoInput`. Sehen Sie sich die folgende vereinfachte Version des Schemas an:

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

Das folgende Abonnement gibt alle `Todo` Updates zurück:

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

Wenn Sie das vorherige Abonnement ändern, um das Feldargument hinzuzufügen`owner: null`, stellen Sie jetzt eine andere Frage. Dieses Abonnement registriert jetzt den Client, um über alle `Todo` Updates informiert zu werden, für die kein Eigentümer angegeben wurde.

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

**Anmerkung**  
**Seit dem 1. Januar 2022 WebSockets ist MQTT over nicht mehr als Protokoll für GraphQL-Abonnements in verfügbar. AWS AppSync APIs Pure WebSockets ist das einzige Protokoll, das in unterstützt wird. AWS AppSync**  
Clients, die auf dem AWS AppSync SDK oder den Amplify-Bibliotheken basieren und nach November 2019 veröffentlicht wurden, verwenden WebSockets standardmäßig automatisch Pure. Durch das Upgrade der Clients auf die neueste Version können sie die Pure WebSockets Engine verwenden AWS AppSync.  
Pure WebSockets bietet eine größere Nutzlast (240 KB), eine größere Auswahl an Client-Optionen und verbesserte CloudWatch Metriken. Weitere Informationen zur Verwendung von Pure WebSocket Clients finden Sie unter[Aufbau eines Echtzeit-Clients in WebSocket AWS AppSync](real-time-websocket-client.md).

# Generisches pub/sub APIs Powered by Serverless WebSockets in AWS AppSync
<a name="aws-appsync-real-time-create-generic-api-serverless-websocket"></a>

**Wichtig**  
Ab dem 13. März 2025 können Sie WebSockets mithilfe von AWS AppSync Events eine PubSub Echtzeit-API erstellen. Weitere Informationen finden Sie unter [Ereignisse veröffentlichen über WebSocket](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) im *AWS AppSync Events Developer Guide*.

Bei einigen Anwendungen ist lediglich Simple erforderlich WebSocket APIs , bei dem sich die Kunden einen bestimmten Kanal oder ein bestimmtes Thema anhören. Generische JSON-Daten ohne spezifische Form oder stark typisierte Anforderungen können nach einem einfachen Publish-Subscribe-Muster (Pub/Sub) an Kunden weitergegeben werden, die sich einen dieser Kanäle anhören.

Wird verwendet AWS AppSync , um einfache Implementierungen pub/sub WebSocket APIs mit wenig bis gar keinen GraphQL-Kenntnissen innerhalb von Minuten durchzuführen, indem GraphQL-Code sowohl auf dem API-Backend als auch auf der Clientseite automatisch generiert wird.

## Pub-Sub erstellen und konfigurieren APIs
<a name="aws-appsync-real-time-enhanced-filtering-using-pub-sub-apis"></a>

Gehen Sie zunächst wie folgt vor: 

1. Melden Sie sich bei der an AWS-Managementkonsole und öffnen Sie die [AppSync Konsole](https://console.aws.amazon.com/appsync/).

   1. Wählen Sie im **Dashboard** **Create API (API erstellen)** aus.

1. Wählen Sie auf dem nächsten Bildschirm **Create a real-time API** und dann **Next** aus.

1. Geben Sie einen benutzerfreundlichen Namen für Ihre pub/sub API ein.

1. Sie können [private API-Funktionen](https://docs.aws.amazon.com/appsync/latest/devguide/using-private-apis.html) aktivieren, wir empfehlen jedoch, dies vorerst auszuschalten. Wählen Sie **Weiter** aus.

1. Sie können wählen, ob Sie mit automatisch eine funktionierende pub/sub API generieren möchten WebSockets. Wir empfehlen, diese Funktion vorerst ebenfalls auszuschalten. Wählen Sie **Weiter** aus.

1. Wählen Sie **Create API** und warten Sie dann einige Minuten. Eine neue vorkonfigurierte AWS AppSync Pub/Sub-API wird in Ihrem Konto erstellt. AWS 

Die API verwendet AWS AppSync die integrierten lokalen Resolver (weitere Informationen zur Verwendung lokaler Resolver finden Sie unter [Tutorial: Lokale Resolver](https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-local-resolvers-js.html) im *AWS AppSync Entwicklerhandbuch*), um mehrere temporäre pub/sub Kanäle und WebSocket Verbindungen zu verwalten. Dabei werden Daten automatisch nur auf der Grundlage des Kanalnamens an abonnierte Clients übermittelt und gefiltert. API-Aufrufe werden mit einem API-Schlüssel autorisiert.

Nach der Bereitstellung der API stehen Ihnen einige zusätzliche Schritte zur Generierung von Client-Code und dessen Integration in Ihre Client-Anwendung zur Verfügung. Als Beispiel für die schnelle Integration eines Clients wird in diesem Handbuch eine einfache React-Webanwendung verwendet.

1. Erstellen Sie zunächst eine Boilerplate-React-App mit [NPM](https://www.npmjs.com/get-npm) auf Ihrem lokalen Computer:

   ```
   $ npx create-react-app mypubsub-app 
   $ cd mypubsub-app
   ```
**Anmerkung**  
In diesem Beispiel werden die [Amplify-Bibliotheken](https://docs.amplify.aws/lib/) verwendet, um Clients mit der Backend-API zu verbinden. Es ist jedoch nicht erforderlich, ein Amplify CLI-Projekt lokal zu erstellen. Während React in diesem Beispiel der Client der Wahl ist, unterstützen Amplify-Bibliotheken auch iOS-, Android- und Flutter-Clients und bieten dieselben Funktionen in diesen unterschiedlichen Laufzeiten. [Die unterstützten Amplify-Clients bieten einfache Abstraktionen für die Interaktion mit AWS AppSync GraphQL-API-Backends mit wenigen Codezeilen, einschließlich integrierter WebSocket Funktionen, die vollständig mit dem Echtzeitprotokoll kompatibel sind:AWS AppSync WebSocket ](https://docs.aws.amazon.com/appsync/latest/devguide/real-time-websocket-client.html)  

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

1. Wählen Sie in der AWS AppSync Konsole dann **Herunterladen** aus **JavaScript**, um eine einzelne Datei mit den API-Konfigurationsdetails und dem generierten GraphQL-Operationscode herunterzuladen.

1. Kopieren Sie die heruntergeladene Datei in den `/src` Ordner in Ihrem React-Projekt.

1. Ersetzen Sie als Nächstes den Inhalt der vorhandenen `src/App.js` Boilerplate-Datei durch den in der Konsole verfügbaren Beispiel-Client-Code.

1. Verwenden Sie den folgenden Befehl, um die Anwendung lokal zu starten:

   ```
   $ npm start
   ```

1. Um das Senden und Empfangen von Echtzeitdaten zu testen, öffnen Sie zwei Browserfenster und greifen Sie darauf zu*localhost:3000*. Die Beispielanwendung ist so konfiguriert, dass sie generische JSON-Daten an einen fest codierten Kanal mit dem Namen *robots* sendet.

1.  **Geben Sie in einem der Browserfenster den folgenden JSON-Blob in das Textfeld ein und klicken Sie dann auf Senden:** 

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

Beide Browserinstanzen haben den *robots* Kanal abonniert und empfangen die veröffentlichten Daten in Echtzeit, die unten in der Webanwendung angezeigt werden:

![\[Beispiel für eine React-App für API pub/sub\]](http://docs.aws.amazon.com/de_de/appsync/latest/devguide/images/pub-sub-react.png)


Der gesamte erforderliche GraphQL-API-Code, einschließlich des Schemas, der Resolver und der Operationen, wird automatisch generiert, um einen generischen pub/sub Anwendungsfall zu ermöglichen. Im Backend werden Daten mit einer GraphQL-Mutation wie AWS AppSync der folgenden auf dem Echtzeit-Endpunkt veröffentlicht:

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

Abonnenten greifen mit einem entsprechenden GraphQL-Abonnement auf die veröffentlichten Daten zu, die an den jeweiligen temporären Kanal gesendet wurden:

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

## Implementierung von Pub-Sub in bestehende Anwendungen APIs
<a name="aws-appsync-real-time-enhanced-filtering-existing-apps"></a>

Falls Sie nur eine Echtzeitfunktion in einer vorhandenen Anwendung implementieren müssen, kann diese generische pub/sub API-Konfiguration problemlos in jede Anwendung oder API-Technologie integriert werden. Die Verwendung eines einzigen API-Endpunkts für den sicheren Zugriff, die Bearbeitung und Kombination von Daten aus einer oder mehreren Datenquellen in einem einzigen Netzwerkaufruf mit GraphQL bietet zwar Vorteile, es ist jedoch nicht erforderlich, eine bestehende REST-basierte Anwendung von Grund auf neu zu konvertieren oder neu zu erstellen, um die Echtzeitfunktionen nutzen zu können. AWS AppSync Sie könnten beispielsweise einen vorhandenen CRUD-Workload in einem separaten API-Endpunkt haben, wobei Clients Nachrichten oder Ereignisse von der vorhandenen Anwendung an die generische pub/sub API nur in Echtzeit und zu bestimmten pub/sub Zwecken senden und empfangen. 

# Definition erweiterter Abonnementfilter in AWS AppSync
<a name="aws-appsync-real-time-enhanced-filtering"></a>

**Wichtig**  
Ab dem 13. März 2025 können Sie WebSockets mithilfe von AWS AppSync Events eine PubSub Echtzeit-API erstellen. Weitere Informationen finden Sie unter [Ereignisse veröffentlichen über WebSocket](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) im *AWS AppSync Events Developer Guide*.

In AWS AppSync können Sie die Geschäftslogik für die Datenfilterung im Backend direkt in den GraphQL-API-Abonnement-Resolvern definieren und aktivieren, indem Sie Filter verwenden, die zusätzliche logische Operatoren unterstützen. Im Gegensatz zu den Abonnementargumenten, die in der Abonnementabfrage im Client definiert sind, können Sie diese Filter konfigurieren. Weitere Hinweise zur Verwendung von Abonnementargumenten finden Sie unter[Abonnementargumente verwenden](aws-appsync-real-time-data.md#using-subscription-arguments). Eine Liste der Operatoren finden Sie unter[AWS AppSync Referenz zum Hilfsprogramm für Resolver-Mapping-Vorlagen](resolver-util-reference.md).

Für die Zwecke dieses Dokuments unterteilen wir die Echtzeit-Datenfilterung in die folgenden Kategorien:
+ **Grundlegendes Filtern** — Filterung auf der Grundlage von vom Kunden definierten Argumenten in der Abonnementabfrage.
+ **Verbesserte Filterung — Filterung** auf der Grundlage einer Logik, die zentral im AWS AppSync Service-Backend definiert ist.

In den folgenden Abschnitten wird erklärt, wie erweiterte Abonnementfilter konfiguriert werden und wie sie in der Praxis angewendet werden.

## Definieren von Abonnements in Ihrem GraphQL-Schema
<a name="aws-appsync-real-time-enhanced-filtering-using-subscription-filters"></a>

Um erweiterte Abonnementfilter zu verwenden, definieren Sie das Abonnement im GraphQL-Schema und definieren dann den erweiterten Filter mithilfe einer Filtererweiterung. Um zu veranschaulichen, wie die erweiterte Abonnementfilterung funktioniert AWS AppSync, verwenden Sie als Beispiel das folgende GraphQL-Schema, das eine Ticket-Management-System-API definiert:

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

Angenommen, Sie erstellen eine `NONE` Datenquelle für Ihre API und fügen dann mithilfe dieser Datenquelle einen Resolver an die `createTicket` Mutation an. Ihre Handler könnten so aussehen:

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

**Anmerkung**  
Verbesserte Filter werden im Handler des GraphQL-Resolvers in einem bestimmten Abonnement aktiviert. Weitere Informationen finden Sie in der [Resolver-Referenz](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-js-version.html).

Um das Verhalten des erweiterten Filters zu implementieren, müssen Sie die `extensions.setSubscriptionFilter()` Funktion verwenden, um einen Filterausdruck zu definieren, der anhand veröffentlichter Daten aus einer GraphQL-Mutation ausgewertet wird, an der die abonnierten Clients interessiert sein könnten. [Weitere Informationen zu den Filtererweiterungen finden Sie unter Erweiterungen.](https://docs.aws.amazon.com//appsync/latest/devguide/extensions-js.html)

Im folgenden Abschnitt wird erklärt, wie Sie Filtererweiterungen verwenden, um erweiterte Filter zu implementieren.

## Erstellen erweiterter Abonnementfilter mithilfe von Filtererweiterungen
<a name="aws-appsync-real-time-enhanced-filtering-defining-filters"></a>

Verbesserte Filter werden in JSON in den Antworthandler der Resolver des Abonnements geschrieben. Filter können in einer Liste zusammengefasst werden, die als a `filterGroup` bezeichnet wird. Filter werden mithilfe von mindestens einer Regel definiert, die jeweils Felder, Operatoren und Werte enthält. Definieren wir einen neuen Resolver`onSpecialTicketCreated`, der einen erweiterten Filter einrichtet. Sie können mehrere Regeln in einem Filter konfigurieren, die mithilfe der UND-Logik ausgewertet werden, während mehrere Filter in einer Filtergruppe mithilfe der OR-Logik ausgewertet werden:

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

Basierend auf den im vorherigen Beispiel definierten Filtern werden wichtige Tickets automatisch an abonnierte API-Clients weitergeleitet, wenn ein Ticket erstellt wird mit:
+ `priority`Stufe oder `high` `medium`

  AND 
+ `severity`Stufe größer oder gleich `7` (`ge`)

ODER 
+ `classification`Ticket gesetzt auf `Security` 

  AND 
+ `group`Die Zuweisung ist auf `admin` oder gesetzt `operators`

![\[Beispiel für eine Ticketfilterabfrage\]](http://docs.aws.amazon.com/de_de/appsync/latest/devguide/images/aws-priority-example.png)


Im Abonnement-Resolver definierte Filter (erweiterte Filterung) haben Vorrang vor Filtern, die nur auf Abonnementargumenten basieren (grundlegende Filterung). Weitere Informationen zur Verwendung von Abonnementargumenten finden Sie unter [Abonnementargumente verwenden](https://docs.aws.amazon.com//appsync/latest/devguide/aws-appsync-real-time-data.html#using-subscription-arguments)).

Wenn ein Argument im GraphQL-Schema des Abonnements definiert und erforderlich ist, erfolgt die Filterung auf der Grundlage des angegebenen Arguments nur, wenn das Argument in der Regel in der Methode des Resolvers definiert ist`extensions.setSubscriptionFilter()`. Wenn der Abonnement-Resolver jedoch keine `extensions` Filtermethoden enthält, werden die im Client definierten Argumente nur für die grundlegende Filterung verwendet. Sie können die Standardfilterung und die erweiterte Filterung nicht gleichzeitig verwenden.

Sie können die [`context`Variable](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html) in der Filtererweiterungslogik des Abonnements verwenden, um auf Kontextinformationen zur Anfrage zuzugreifen. Wenn Sie beispielsweise Amazon Cognito User Pools, OIDC oder benutzerdefinierte Lambda-Autorisierer für die Autorisierung verwenden, können Sie Informationen über Ihre Benutzer abrufen, sobald das Abonnement eingerichtet wird. `context.identity` Sie können diese Informationen verwenden, um Filter auf der Grundlage der Identität Ihrer Benutzer einzurichten.

Gehen Sie nun davon aus, dass Sie das erweiterte Filterverhalten für implementieren möchten`onGroupTicketCreated`. Für das `onGroupTicketCreated` Abonnement ist ein obligatorischer `group` Name als Argument erforderlich. Bei der Erstellung wird den Tickets automatisch ein `pending` Status zugewiesen. Sie können einen Abonnementfilter einrichten, um nur neu erstellte Tickets zu erhalten, die zu der angegebenen Gruppe gehören:

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

Wenn Daten mithilfe einer Mutation wie im folgenden Beispiel veröffentlicht werden:

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

Abonnierte Kunden warten darauf, dass die Daten automatisch weitergeleitet werden, WebSockets sobald ein Ticket mit der `createTicket` Mutation erstellt wird:

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

Clients können ohne Argumente abonniert werden, da die Filterlogik im AWS AppSync Service mit erweiterter Filterung implementiert ist, wodurch der Client-Code vereinfacht wird. Clients erhalten Daten nur, wenn die definierten Filterkriterien erfüllt sind.

## Definition erweiterter Filter für verschachtelte Schemafelder
<a name="aws-appsync-real-time-enhanced-filters-nested-schema-fields.title"></a>

Sie können die erweiterte Abonnementfilterung verwenden, um verschachtelte Schemafelder zu filtern. Angenommen, wir haben das Schema aus dem vorherigen Abschnitt geändert, um Standort- und Adresstypen einzubeziehen:

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

Mit diesem Schema können Sie ein `.` Trennzeichen verwenden, um die Verschachtelung darzustellen. Im folgenden Beispiel wird eine Filterregel für ein verschachteltes Schemafeld unter hinzugefügt. `location.address.country` Das Abonnement wird ausgelöst, wenn die Adresse des Tickets wie folgt gesetzt `USA` ist:

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

Steht im obigen Beispiel `location` für Verschachtelungsebene eins, `address` für Verschachtelungsebene zwei und `country` für Verschachtelungsebene drei, die alle durch das Trennzeichen getrennt sind. `.`

Sie können dieses Abonnement testen, indem Sie die folgende Mutation verwenden: `createTicket`

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

## Definition erweiterter Filter vom Client aus
<a name="aws-appsync-real-time-enhanced-filtering-defining-from-client"></a>

Sie können die grundlegende Filterung in GraphQL mit [Abonnementargumenten](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-data.html#using-subscription-arguments) verwenden. Der Client, der den Aufruf in der Abonnementabfrage durchführt, definiert die Werte der Argumente. Wenn erweiterte Filter in einem AWS AppSync Abonnement-Resolver mit der `extensions` Filterung aktiviert werden, haben die im Resolver definierten Backend-Filter Vorrang und Priorität.

Konfigurieren Sie dynamische, vom Client definierte erweiterte Filter mithilfe eines Arguments im Abonnement. `filter` Wenn Sie diese Filter konfigurieren, müssen Sie das GraphQL-Schema aktualisieren, um das neue Argument widerzuspiegeln:

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

Der Client kann dann eine Abonnementabfrage wie im folgenden Beispiel senden:

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

Sie können die Abfragevariable wie im folgenden Beispiel konfigurieren:

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

Das `util.transform.toSubscriptionFilter()` Resolver-Hilfsprogramm kann in der Vorlage für die Zuordnung von Abonnementantworten implementiert werden, um den im Abonnementargument definierten Filter für jeden Client anzuwenden:

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

Mit dieser Strategie können Kunden ihre eigenen Filter definieren, die eine erweiterte Filterlogik und zusätzliche Operatoren verwenden. Filter werden zugewiesen, wenn ein bestimmter Client die Abonnementabfrage in einer sicheren WebSocket Verbindung aufruft. Weitere Informationen zum Transformationsprogramm für erweiterte Filterung, einschließlich des Formats der Payload der `filter` Abfragevariablen, finden Sie unter Übersicht über [JavaScriptResolver](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html).

## Zusätzliche erweiterte Filtereinschränkungen
<a name="aws-appsync-real-time-enhanced-filtering-additional-restrictions"></a>

Im Folgenden sind mehrere Anwendungsfälle aufgeführt, in denen erweiterte Filter zusätzlichen Einschränkungen unterliegen:
+ Verbesserte Filter unterstützen keine Filterung für Objektlisten der obersten Ebene. In diesem Anwendungsfall werden veröffentlichte Daten aus der Mutation bei erweiterten Abonnements ignoriert.
+ AWS AppSync unterstützt bis zu fünf Verschachtelungsebenen. Filter für Schemafelder, die nach der Verschachtelungsebene fünf liegen, werden ignoriert. Nehmen Sie die unten stehende GraphQL-Antwort. Das `continent` Eingabefeld `venue.address.country.metadata.continent` ist zulässig, da es sich um ein Nest der Stufe 5 handelt. Da `venue.address.country.metadata.capital.financial` es `financial` sich jedoch um ein Nest der Stufe sechs handelt, funktioniert der Filter nicht:

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

# WebSocket Verbindungen mithilfe von Filtern abbestellen in AWS AppSync
<a name="aws-appsync-real-time-invalidation"></a>

**Wichtig**  
Ab dem 13. März 2025 können Sie WebSockets mithilfe von AWS AppSync Events eine PubSub Echtzeit-API erstellen. Weitere Informationen finden Sie unter [Ereignisse veröffentlichen über WebSocket](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) im *AWS AppSync Events Developer Guide*.

In AWS AppSync können Sie eine WebSocket Verbindung mit einem verbundenen Client auf der Grundlage einer bestimmten Filterlogik zwangsweise abbestellen und schließen (für ungültig erklären). Dies ist in autorisierungsbezogenen Szenarien nützlich, z. B. wenn Sie einen Benutzer aus einer Gruppe entfernen.

Die Invalidierung eines Abonnements erfolgt als Reaktion auf eine in einer Mutation definierte Nutzlast. Wir empfehlen, Mutationen, mit denen Abonnementverbindungen ungültig gemacht werden, als administrative Operationen in Ihrer API zu behandeln und die Berechtigungen entsprechend einzuschränken, indem Sie ihre Verwendung auf einen Admin-Benutzer, eine Gruppe oder einen Back-End-Dienst beschränken. Verwenden Sie beispielsweise Schemaautorisierungsrichtlinien wie `@aws_auth(cognito_groups: ["Administrators"])` oder. `@aws_iam` Weitere Informationen finden Sie unter [Zusätzliche Autorisierungsmodi verwenden](https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html#using-additional-authorization-modes).

Invalidierungsfilter verwenden dieselbe Syntax und Logik wie [erweiterte Abonnementfilter](https://docs.aws.amazon.com/appsync/latest/devguide/aws-appsync-real-time-enhanced-filtering.html). Definieren Sie diese Filter mithilfe der folgenden Dienstprogramme:
+ `extensions.invalidateSubscriptions()`— Definiert im Response-Handler des GraphQL-Resolvers für eine Mutation.
+ `extensions.setSubscriptionInvalidationFilter()`— Definiert im Response-Handler des GraphQL-Resolvers für die mit der Mutation verknüpften Abonnements.

[Weitere Informationen zu Erweiterungen der Invalidierungsfilterung finden Sie JavaScript in der Übersicht über Resolver.](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html)

## Verwenden der Abonnement-Invalidierung
<a name="aws-appsync-real-time-invalidation-using-invalidations"></a>

Verwenden Sie das folgende GraphQL-Schema, um zu sehen AWS AppSync, wie die Invalidierung von Abonnements funktioniert:

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

Definieren Sie einen Invalidierungsfilter im `removeUserFromGroup` Mutationsauflösungscode:

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

Wenn die Mutation aufgerufen wird, werden die im `payload` Objekt definierten Daten verwendet, um das in definierte Abonnement zu kündigen. `subscriptionField` In der Antwortzuordnungsvorlage des `onGroupMessageCreated` Abonnements ist auch ein Invalidierungsfilter definiert. 

Wenn die `extensions.invalidateSubscriptions()` Payload eine ID enthält, die der ID des IDs abonnierten Clients entspricht, wie im Filter definiert, wird das entsprechende Abonnement abgemeldet. Außerdem wird die Verbindung geschlossen. WebSocket Definieren Sie den Abonnement-Resolver-Code für das `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;
}
```

Beachten Sie, dass im Antworthandler für Abonnements sowohl Abonnementfilter als auch Invalidierungsfilter gleichzeitig definiert werden können.

Nehmen wir  beispielsweise an, dass Client A mithilfe der folgenden Abonnementanforderung einen neuen Benutzer mit der ID `user-1` für die Gruppe `group-1` mit der ID abonniert:

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

AWS AppSync führt den Abonnement-Resolver aus, der Abonnement- und Invalidierungsfilter generiert, wie in der vorherigen `onGroupMessageCreated` Antwortzuordnungsvorlage definiert. Für Client A ermöglichen die Abonnementfilter das Senden von Daten nur an`group-1`, und die Invalidierungsfilter sind sowohl für als auch definiert. `user-1` `group-1`

Gehen Sie nun davon aus, dass Client B mithilfe der folgenden Abonnementanforderung `user-2` einen Benutzer mit der ID für eine Gruppe `group-2` mit der ID abonniert:

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

AWS AppSync führt den Abonnement-Resolver aus, der Abonnement- und Invalidierungsfilter generiert. Für Client B ermöglichen die Abonnementfilter das Senden von Daten nur an`group-2`, und die Invalidierungsfilter sind sowohl für als auch definiert. `user-2` `group-2`

Gehen Sie als Nächstes davon aus, dass eine neue Gruppennachricht mit der ID mithilfe einer Mutationsanforderung wie im folgenden Beispiel erstellt `message-1` wird:

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

Abonnierte Clients, die den definierten Filtern entsprechen, erhalten automatisch die folgenden Datennutzdaten über: WebSockets

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

Client A erhält die Nachricht, weil die Filterkriterien mit dem definierten Abonnementfilter übereinstimmen. Client B empfängt die Nachricht jedoch nicht, da der Benutzer nicht Teil von ist`group-1`. Außerdem entspricht die Anfrage nicht dem Abonnementfilter, der im Abonnement-Resolver definiert ist.

Gehen Sie abschließend davon aus, dass `user-1` dies aus der `group-1` Verwendung der folgenden Mutationsanforderung entfernt wurde:

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

Die Mutation leitet eine Abonnement-Invalidierung ein, wie sie in ihrem `extensions.invalidateSubscriptions()` Resolver-Antworthandlercode definiert ist. AWS AppSync meldet dann Client A ab und schließt seine Verbindung. WebSocket Client B ist davon nicht betroffen, da die in der Mutation definierte Payload für die Invalidierung nicht mit seinem Benutzer oder seiner Gruppe übereinstimmt.

Wenn eine Verbindung für AWS AppSync ungültig erklärt wird, erhält der Client eine Nachricht, in der bestätigt wird, dass er sich abgemeldet hat:

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

## Verwendung von Kontextvariablen in Filtern für die Invalidierung von Abonnements
<a name="aws-appsync-real-time-invalidation-context"></a>

Wie bei erweiterten Abonnementfiltern können Sie die [`context`Variable](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html) in der Erweiterung für den Abonnement-Invalidierungsfilter verwenden, um auf bestimmte Daten zuzugreifen.

Beispielsweise ist es möglich, eine E-Mail-Adresse als Payload für die Invalidierung in der Mutation zu konfigurieren und sie dann mit dem E-Mail-Attribut oder dem Anspruch eines abonnierten Benutzers abzugleichen, der mit Amazon Cognito Cognito-Benutzerpools oder OpenID Connect autorisiert ist. Der im `extensions.setSubscriptionInvalidationFilter()` Abonnement-Invalidator definierte Invalidierungsfilter prüft, ob die durch die `extensions.invalidateSubscriptions()` Payload der Mutation festgelegte E-Mail-Adresse mit der E-Mail-Adresse übereinstimmt, die aus dem JWT-Token des Benutzers abgerufen wurde, wodurch die Ungültigerklärung eingeleitet wird. `context.identity.claims.email`

# Aufbau eines Echtzeit-Clients in WebSocket AWS AppSync
<a name="real-time-websocket-client"></a>

**Wichtig**  
Ab dem 13. März 2025 können Sie WebSockets mithilfe von AWS AppSync Events eine PubSub Echtzeit-API erstellen. Weitere Informationen finden Sie unter [Ereignisse veröffentlichen über WebSocket](https://docs.aws.amazon.com/appsync/latest/eventapi/publish-websocket.html) im *AWS AppSync Events Developer Guide*.

AWS AppSyncDer WebSocket Echtzeitclient ermöglicht GraphQL-Abonnements in einem mehrstufigen Prozess. Der Client stellt zunächst eine WebSocket Verbindung mit dem AWS AppSync Echtzeit-Endpunkt her, sendet eine Nachricht zur Verbindungsinitialisierung und wartet auf die Bestätigung. Nach erfolgreicher Verbindung registriert der Client Abonnements, indem er Startnachrichten mit eindeutigen IDs und GraphQL-Abfragen sendet. AWS AppSync bestätigt erfolgreiche Abonnements mit Bestätigungsnachrichten. Der Client wartet dann auf Abonnementereignisse, die durch entsprechende Mutationen ausgelöst werden. AWS AppSync Sendet regelmäßig Keep-Alive-Nachrichten, um die Verbindung aufrechtzuerhalten. Wenn der Vorgang abgeschlossen ist, hebt der Client die Registrierung der Abonnements auf, indem er Stoppnachrichten sendet. Dieses System unterstützt mehrere Abonnements über eine einzige WebSocket Verbindung und unterstützt verschiedene Autorisierungsmodi, darunter API-Schlüssel, Amazon Cognito Cognito-Benutzerpools, IAM und Lambda.

## WebSocket Client-Implementierung in Echtzeit für GraphQL-Abonnements
<a name="appsynclong-real-time-websocket-client-implementation-guide-for-graphql-subscriptions"></a>

Das folgende Sequenzdiagramm und die folgenden Schritte zeigen den Echtzeit-Abonnement-Workflow zwischen dem WebSocket Client, dem HTTP-Client und AWS AppSync.

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


1. Der Client stellt eine WebSocket Verbindung mit dem AWS AppSync Echtzeit-Endpunkt her. Bei einem Netzwerkfehler sollte der Client einen exponentiellen Backoff-Jitter ausführen. Weitere Informationen finden Sie unter [Exponentieller Backoff und Jitter](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/) im Architektur-Blog. AWS 

1. (Optional) Nach dem erfolgreichen WebSocket Verbindungsaufbau sendet der Client eine Nachricht. `connection_init`

1. Wenn `connection_init` gesendet, wartet der Client auf eine `connection_ack` Nachricht von AWS AppSync. Diese Nachricht enthält einen `connectionTimeoutMs` Parameter, der die maximale Wartezeit in Millisekunden für eine `"ka"` (Keep-Alive-) Nachricht angibt.

1. AWS AppSync sendet regelmäßig Nachrichten. `"ka"` Der Client verfolgt die Zeit, zu der er jede `"ka"` Nachricht empfangen hat. Wenn der Client innerhalb von `connectionTimeoutMs` Millisekunden keine `"ka"` Nachricht empfängt, sollte der Client die Verbindung schließen.

1. Der Client registriert das Abonnement, indem er eine `start`-Abonnementnachricht sendet. Eine einzelne WebSocket Verbindung unterstützt mehrere Abonnements, auch wenn sie sich in unterschiedlichen Autorisierungsmodi befinden.

1. Der Client wartet darauf AWS AppSync , dass `start_ack` Nachrichten gesendet werden, um erfolgreiche Abonnements zu bestätigen. Wenn ein Fehler auftritt, wird eine `"type": "error"` Meldung AWS AppSync zurückgegeben.

1. Der Client wartet auf Abonnementereignisse, die gesendet werden, nachdem eine entsprechende Mutation aufgerufen wurde. Abfragen und Mutationen werden normalerweise `https://` an den AWS AppSync GraphQL-Endpunkt gesendet. Abonnements werden mithilfe von secure WebSocket (`wss://`) über den AWS AppSync Echtzeit-Endpunkt abgewickelt.

1. Der Client hebt die Registrierung des Abonnements auf, indem er eine `stop`-Abonnementnachricht sendet.

1. Nachdem der Client die Registrierung aller Abonnements aufgehoben und überprüft hat, dass keine Nachrichten über das übertragen werden WebSocket, kann er die WebSocket Verbindung trennen.

## Handshake-Details zum Herstellen der Verbindung WebSocket
<a name="handshake-details-to-establish-the-websocket-connection"></a>

Um eine Verbindung herzustellen und einen erfolgreichen Handshake mit zu initiieren AWS AppSync, benötigt ein WebSocket Client Folgendes:
+ Der AWS AppSync Echtzeit-Endpunkt
+ Header — Enthalten Informationen, die für den AWS AppSync Endpunkt und die Autorisierung relevant sind. AWS AppSync unterstützt die folgenden drei Methoden zur Bereitstellung von Headern: 
  + Header per Abfragezeichenfolge
    + Die Header-Informationen sind als Base64-Zeichenfolge codiert, die von einem stringifizierten JSON-Objekt abgeleitet wird. Dieses JSON-Objekt enthält Details, die für den Endpunkt und die AWS AppSync Autorisierung relevant sind. Der Inhalt des JSON-Objekts variiert je nach Autorisierungsmodus.
  + Header über `Sec-WebSocket-Protocol`
    + Eine Base64URL-kodierte Zeichenfolge aus dem stringifizierten JSON-Objekt, die Informationen enthält, die für den AWS AppSync Endpunkt und die Autorisierung relevant sind, wird als Protokoll im Header übergeben. `Sec-WebSocket-Protocol` Der Inhalt des JSON-Objekts variiert je nach Autorisierungsmodus.
  + Header über Standard-HTTP-Header:
    + Header können als Standard-HTTP-Header in der Verbindungsanforderung übergeben werden, ähnlich wie Header für GraphQL-Abfragen und -Mutationen an übergeben werden. AWS AppSync Die Übergabe von Headern über Standard-HTTP-Header wird jedoch für private API-Verbindungsanfragen nicht unterstützt.
+  `payload`— Base64-kodierte Zeichenfolge von. `payload` Payload wird nur benötigt, wenn Header mithilfe einer Abfragezeichenfolge bereitgestellt werden

Mit diesen Anforderungen kann ein WebSocket Client eine Verbindung zu der URL herstellen, die den Echtzeit-Endpunkt mit der Abfragezeichenfolge enthält, die `graphql-ws` WebSocket als Protokoll verwendet wird.

### Erkennung des -Echtzeitendpunkts über den -GraphQL-Endpunkt
<a name="discovering-the-appsync-real-time-endpoint-from-the-appsync-graphql-endpoint"></a>

Der AWS AppSync GraphQL-Endpunkt und der AWS AppSync Echtzeit-Endpunkt unterscheiden sich geringfügig in Protokoll und Domäne. Sie können den GraphQL-Endpunkt mit dem Befehl AWS Command Line Interface `aws appsync get-graphql-api` (AWS CLI) abrufen.

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

****AWS AppSync Echtzeit-Endpunkt:****  
 `wss://example1234567890000.appsync-realtime-api.us-east-1.amazonaws.com/graphql`

Anwendungen können über einen beliebigen HTTP-Client für Abfragen und Mutationen eine Verbindung zum AWS AppSync GraphQL-Endpunkt (`https://`) herstellen. Anwendungen können sich mit einem beliebigen WebSocket Client für Abonnements mit dem AWS AppSync Echtzeit-Endpunkt (`wss://`) verbinden.

Mit benutzerdefinierten Domainnamen können Sie über eine einzige Domain mit beiden Endpunkten interagieren. Wenn Sie beispielsweise `api.example.com` als Ihre benutzerdefinierte Domain konfigurieren, können Sie mit Ihren GraphQL- und Echtzeit-Endpunkten über diese interagieren: URLs

**AWS AppSync GraphQL-Endpunkt für benutzerdefinierte Domänen:**  
`https://api.example.com/graphql`

**AWS AppSync Echtzeit-Endpunkt für benutzerdefinierte Domänen:**  
`wss://api.example.com/graphql/realtime`

## Das Format der Header-Parameter basiert auf dem AWS AppSync API-Autorisierungsmodus
<a name="header-parameter-format-based-on-appsync-api-authorization-mode"></a>

Das Format des in der Verbindungsabfragezeichenfolge verwendeten `header` Objekts hängt vom AWS AppSync API-Autorisierungsmodus ab. Das `host` Feld im Objekt bezieht sich auf den AWS AppSync GraphQL-Endpunkt, der verwendet wird, um die Verbindung zu validieren, auch wenn der `wss://` Aufruf gegen den Echtzeit-Endpunkt erfolgt. Um den Handshake zu initiieren und die autorisierte Verbindung herzustellen, sollte es sich bei `payload` um ein leeres JSON-Objekt handeln. Payload wird nur benötigt, wenn Header per Abfragestring übergeben werden.

In den folgenden Abschnitten werden die Header-Formate für jeden Autorisierungsmodus veranschaulicht.

### API-Schlüssel
<a name="api-key"></a>

#### Kopfzeile des API-Schlüssels
<a name="api-key-list"></a>

**Inhalt der Kopfzeile**
+  `"host": <string>`: Der Host für den AWS AppSync GraphQL-Endpunkt oder Ihren benutzerdefinierten Domainnamen.
+  `"x-api-key": <string>`: Der für die API konfigurierte AWS AppSync API-Schlüssel.

**Beispiel**

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

**Header per Abfragezeichenfolge**

Zunächst wird ein JSON-Objekt, das das `host` und `x-api-key` das enthält, in eine Zeichenfolge umgewandelt. Als Nächstes wird diese Zeichenfolge mithilfe der Base64-Kodierung codiert. Die resultierende Base64-kodierte Zeichenfolge wird als Abfrageparameter mit dem Namen der WebSocket URL hinzugefügt`header`, um die Verbindung mit dem Echtzeit-Endpunkt herzustellen. AWS AppSync Die resultierende Anforderungs-URL hat die folgende Form:

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

Es ist wichtig zu beachten, dass neben dem Base64-codierten Header-Objekt auch ein leeres JSON-Objekt \$1\$1 Base64-codiert und als separater Abfrageparameter in der URL enthalten ist. `payload` WebSocket

**Header über `Sec-WebSocket-Protocol`**

Ein JSON-Objekt, das das `host` und das enthält, `x-api-key` wird in eine Zeichenfolge konvertiert und dann mit der Base64URL-Codierung codiert. Der resultierenden Base64URL-codierten Zeichenfolge wird ein Präfix vorangestellt. `header-` Diese Zeichenfolge mit Präfix wird dann zusätzlich zum `Sec-WebSocket-Protocol` Header als neues Unterprotokoll verwendet, wenn die Verbindung mit dem `graphql-ws` Echtzeit-Endpunkt hergestellt wird. WebSocket AWS AppSync 

Die resultierende Anforderungs-URL hat die folgende Form:

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

Der `Sec-WebSocket-Protocol` Header enthält den folgenden Wert:

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

**Header über Standard-HTTP-Header**

Bei dieser Methode werden die Host- und API-Schlüsselinformationen mithilfe von Standard-HTTP-Headern übertragen, wenn die WebSocket Verbindung mit dem AWS AppSync Echtzeit-Endpunkt hergestellt wird. Die resultierende Anforderungs-URL hat die folgende Form:

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

Die Anforderungsheader würden Folgendes beinhalten:

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

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

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

Inhalt des Headers:
+  `"Authorization": <string>`: Ein JWT-ID-Token. Der Header kann ein [Bearer-Schema](https://datatracker.ietf.org/doc/html/rfc6750#section-2.1) verwenden.
+  `"host": <string>`: Der Host für den AWS AppSync GraphQL-Endpunkt oder Ihren benutzerdefinierten Domainnamen.

Beispiel:

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

**Header per Abfragezeichenfolge**

Zunächst wird ein JSON-Objekt, das das `host` und `Authorization` das enthält, in eine Zeichenfolge umgewandelt. Als Nächstes wird diese Zeichenfolge mithilfe der Base64-Kodierung codiert. Die resultierende Base64-kodierte Zeichenfolge wird als Abfrageparameter mit dem Namen der WebSocket URL hinzugefügt`header`, um die Verbindung mit dem Echtzeit-Endpunkt herzustellen. AWS AppSync Die resultierende Anforderungs-URL hat die folgende Form:

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

Es ist wichtig zu beachten, dass neben dem Base64-codierten Header-Objekt auch ein leeres JSON-Objekt \$1\$1 Base64-codiert und als separater Abfrageparameter in der URL enthalten ist. `payload` WebSocket

**Header über `Sec-WebSocket-Protocol`**

Ein JSON-Objekt, das das `host` und das enthält, `Authorization` wird in eine Zeichenfolge konvertiert und dann mit der Base64URL-Codierung codiert. Der resultierenden Base64URL-codierten Zeichenfolge wird ein Präfix vorangestellt. `header-` Diese Zeichenfolge mit Präfix wird dann zusätzlich zum `Sec-WebSocket-Protocol` Header als neues Unterprotokoll verwendet, wenn die Verbindung mit dem `graphql-ws` Echtzeit-Endpunkt hergestellt wird. WebSocket AWS AppSync 

Die resultierende Anforderungs-URL hat die folgende Form:

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

Der `Sec-WebSocket-Protocol` Header enthält den folgenden Wert:

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

**Header über Standard-HTTP-Header**

Bei dieser Methode werden die Host- und Autorisierungsinformationen beim WebSocket Verbindungsaufbau mit dem Echtzeit-Endpunkt mithilfe von Standard-HTTP-Headern übertragen. AWS AppSync Die resultierende Anforderungs-URL hat die folgende Form:

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

Die Anforderungsheader würden Folgendes beinhalten:

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

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

**Inhalt der Kopfzeile**
+  `"accept": "application/json, text/javascript"`: Ein konstanter `<string>`-Parameter.
+  `"content-encoding": "amz-1.0"`: Ein konstanter `<string>`-Parameter.
+  `"content-type": "application/json; charset=UTF-8"`: Ein konstanter `<string>`-Parameter.
+  `"host": <string>`: Dies ist der Host für den AWS AppSync GraphQL-Endpunkt.
  + `"x-amz-date": <string>`: Der Zeitstempel muss in UTC und im folgenden ISO 8601-Format sein: YYYYMMDD'T'HHMMSS'Z'. Ein gültiger Zeitstempel ist beispielsweise 20150830T123600Z. Der Zeitstempel darf keine Millisekunden enthalten. [Weitere Informationen finden Sie unter Umgang mit Daten in Signature Version 4 in der. *Allgemeine AWS-Referenz*](https://docs.aws.amazon.com/general/latest/gr/sigv4-date-handling.html)
  +  `"X-Amz-Security-Token": <string>`: Das AWS Sitzungstoken, das bei der Verwendung temporärer Sicherheitsanmeldedaten erforderlich ist. Weitere Informationen finden Sie unter [Verwenden von temporären Anmeldeinformationen mit AWS -Ressourcen ](https://docs.aws.amazon.com//IAM/latest/UserGuide/id_credentials_temp_use-resources.html) im *IAM-Benutzerhandbuch*.
  +  `"Authorization": <string>`: Signaturinformationen der Version 4 (Sigv4) für den AWS AppSync Endpunkt. Weitere Informationen zum Signiervorgang finden Sie unter [Aufgabe 4: Hinzufügen der Signatur zur HTTP-Anfrage](https://docs.aws.amazon.com/general/latest/gr/sigv4-add-signature-to-request.html) in der *Allgemeine AWS-Referenz*.

Die Sigv4-Signatur-HTTP-Anforderung enthält eine kanonische URL. Dies ist der AWS AppSync -GraphQL-Endpunkt, dem `/connect` angefügt wurde. Die AWS Service-Endpunkt-Region ist dieselbe Region, in der Sie die AWS AppSync API verwenden, und der Dienstname ist „appsync“. Die HTTP-Anforderung für die Signatur ist wie folgt:

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

**Beispiel**

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

**Header per Abfragezeichenfolge**

Zunächst wird ein JSON-Objekt, das den `host` (AWS AppSync GraphQL-Endpunkt) und die anderen Autorisierungsheader enthält, in eine Zeichenfolge umgewandelt. Als Nächstes wird diese Zeichenfolge mithilfe der Base64-Kodierung codiert. Die resultierende Base64-kodierte Zeichenfolge wird der WebSocket URL als Abfrageparameter mit dem Namen hinzugefügt. `header` Die resultierende Anforderungs-URL hat das folgende Format:

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

Es ist wichtig zu beachten, dass neben dem Base64-codierten Header-Objekt auch ein leeres JSON-Objekt \$1\$1 Base64-codiert und als separater Abfrageparameter in der URL enthalten ist. `payload` WebSocket

**Header über `Sec-WebSocket-Protocol`**

Ein JSON-Objekt, das die `host` und die anderen Autorisierungsheader enthält, wird in eine Zeichenfolge konvertiert und dann mit der Base64URL-Kodierung codiert. Der resultierenden Base64URL-codierten Zeichenfolge wird ein Präfix vorangestellt. `header-` Diese Zeichenfolge mit Präfix wird dann zusätzlich zum `Sec-WebSocket-Protocol` Header als neues Unterprotokoll verwendet, wenn die Verbindung mit dem `graphql-ws` Echtzeit-Endpunkt hergestellt wird. WebSocket AWS AppSync 

Die resultierende Anforderungs-URL hat die folgende Form:

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

Der `Sec-WebSocket-Protocol` Header enthält den folgenden Wert:

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

**Header über Standard-HTTP-Header**

Bei dieser Methode werden der Host und die anderen Autorisierungsinformationen beim WebSocket Verbindungsaufbau mit dem Echtzeit-Endpunkt mithilfe von Standard-HTTP-Headern übertragen. AWS AppSync Die resultierende Anforderungs-URL hat die folgende Form:

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

Die Anforderungsheader würden Folgendes beinhalten:

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

Um die Anfrage mit einer benutzerdefinierten Domain zu signieren:

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

**Beispiel**

```
{
  "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 mit Abfragezeichenfolge anfordern**

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

**Anmerkung**  
Eine WebSocket Verbindung kann mehrere Abonnements haben (auch mit unterschiedlichen Authentifizierungsmodi). Eine Möglichkeit, dies zu implementieren, besteht darin, eine WebSocket Verbindung für das erste Abonnement herzustellen und sie dann zu schließen, wenn das letzte Abonnement nicht registriert ist. Sie können dies optimieren, indem Sie einige Sekunden warten, bevor Sie die WebSocket Verbindung schließen, falls die App unmittelbar nach der Aufhebung der Registrierung des letzten Abonnements abonniert wird. Beispiel: Wenn eine mobile App von einem Bildschirm auf einen anderen wechselt, beendet sie beim *Aushängen* ein Abonnement und beim Einhängen des Ereignisses *startet* sie ein anderes Abonnement.

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

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

**Inhalt der Kopfzeile**
+  `"Authorization": <string>`: Der Wert, der als übergeben wird`authorizationToken`.
+  `"host": <string>`: Der Host für den AWS AppSync GraphQL-Endpunkt oder Ihren benutzerdefinierten Domainnamen.

**Beispiel**

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

**Header per Abfragezeichenfolge**

Zunächst wird ein JSON-Objekt, das das `host` und `Authorization` das enthält, in eine Zeichenfolge umgewandelt. Als Nächstes wird diese Zeichenfolge mithilfe der Base64-Kodierung codiert. Die resultierende Base64-kodierte Zeichenfolge wird als Abfrageparameter mit dem Namen der WebSocket URL hinzugefügt`header`, um die Verbindung mit dem Echtzeit-Endpunkt herzustellen. AWS AppSync Die resultierende Anforderungs-URL hat die folgende Form:

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

Es ist wichtig zu beachten, dass neben dem Base64-codierten Header-Objekt auch ein leeres JSON-Objekt \$1\$1 Base64-codiert und als separater Abfrageparameter in der URL enthalten ist. `payload` WebSocket

**Header über `Sec-WebSocket-Protocol`**

Ein JSON-Objekt, das das `host` und das enthält, `Authorization` wird in eine Zeichenfolge konvertiert und dann mit der Base64URL-Codierung codiert. Der resultierenden Base64URL-codierten Zeichenfolge wird ein Präfix vorangestellt. `header-` Diese Zeichenfolge mit Präfix wird dann zusätzlich zum `Sec-WebSocket-Protocol` Header als neues Unterprotokoll verwendet, wenn die Verbindung mit dem `graphql-ws` Echtzeit-Endpunkt hergestellt wird. WebSocket AWS AppSync 

Die resultierende Anforderungs-URL hat die folgende Form:

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

Der `Sec-WebSocket-Protocol` Header enthält den folgenden Wert:

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

**Header über Standard-HTTP-Header**

Bei dieser Methode werden die Host- und Autorisierungsinformationen beim WebSocket Verbindungsaufbau mit dem Echtzeit-Endpunkt mithilfe von Standard-HTTP-Headern übertragen. AWS AppSync Die resultierende Anforderungs-URL hat die folgende Form:

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

Die Anforderungsheader würden Folgendes beinhalten:

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

## Betrieb in Echtzeit WebSocket
<a name="real-time-websocket-operation"></a>

Nach dem Initiieren eines erfolgreichen WebSocket Handshakes mit muss der Client eine nachfolgende Nachricht senden AWS AppSync, mit der er sich AWS AppSync für verschiedene Operationen verbinden kann. Diese Nachrichten benötigen die folgenden Daten:
+  `type`: Typ der Operation.
+  `id`: Eine eindeutige Kennung für das Abonnement. Für diesen Zweck sollte eine UUID verwendet werden.
+  `payload`: Die zugehörige Nutzlast, abhängig vom Vorgangstyp.

Das `type` Feld ist das einzige Pflichtfeld; die `payload` Felder `id` und sind optional.

### Reihenfolge der Ereignisse
<a name="sequence-of-events"></a>

Um die Abonnementanfrage erfolgreich zu initiieren, einzurichten, zu registrieren und zu verarbeiten, muss der Kunde die folgende Reihenfolge einhalten:

1. Initialisierung der Verbindung (`connection_init`)

1. Bestätigung der Verbindung (`connection_ack`)

1. Registrierung des Abonnements (`start`)

1. Bestätigung des Abonnements (`start_ack`)

1. Verarbeitung des Abonnements (`data`)

1. Aufhebung der Registrierung des Abonnements (`stop`)

## Nachricht über die Initialisierung der Verbindung
<a name="connection-init-message"></a>

(Optional) Nach einem erfolgreichen Handshake kann der Client die `connection_init` Nachricht senden, um mit der Kommunikation mit dem AWS AppSync Echtzeit-Endpunkt zu beginnen. Die Nachricht ist eine Zeichenfolge, die durch die Stringifizierung des JSON-Objekts wie folgt abgerufen wurde:

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

## Nachricht über die Bestätigung der Verbindung
<a name="connection-acknowledge-message"></a>

Nach dem Senden der Nachricht `connection_init` muss der Client auf die Nachricht `connection_ack` warten. Alle Nachrichten, die vor dem Empfang gesendet wurden, `connection_ack` werden ignoriert. Die Nachricht sollte wie folgt lauten:

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

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

Zusätzlich zur Verbindungsbestätigungsnachricht empfängt der Client regelmäßig Keep-Alive-Nachrichten. Wenn der Client innerhalb des Verbindungstimeouts keine Keep-Alive-Nachricht erhält, sollte der Client die Verbindung schließen. AWS AppSync sendet weiterhin diese Nachrichten und verwaltet die registrierten Abonnements, bis die Verbindung automatisch beendet wird (nach 24 Stunden). Keep-Alive-Nachrichten sind Heartbeats und müssen vom Client nicht bestätigt werden.

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

## Nachricht über die Abonnementregistrierung
<a name="subscription-registration-message"></a>

Nachdem der Client eine `connection_ack` Nachricht erhalten hat, kann er Abonnementregistrierungsnachrichten an senden. AWS AppSync Bei diesem Nachrichtentyp handelt es sich um ein stringifiziertes JSON-Objekt, das die folgenden Felder enthält:
+  `"id": <string>`: Die ID des Abonnements. Diese ID muss für jedes Abonnement eindeutig sein, andernfalls gibt der Server einen Fehler zurück, der darauf hinweist, dass die Abonnement-ID doppelt vorhanden ist.
+  `"type": "start"`: Ein konstanter `<string>`-Parameter.
+  `"payload": <Object>`: Ein Objekt, das die für das Abonnement relevanten Informationen enthält.
  +  `"data": <string>`: Ein stringifiziertes JSON-Objekt, das eine GraphQL-Abfrage und Variablen enthält.
    +  `"query": <string>`: Eine GraphQL-Operation.
    +  `"variables": <Object>`: Ein Objekt, das die Variablen für die Abfrage enthält.
  +  `"extensions": <Object>`: Ein Objekt, das ein Autorisierungsobjekt enthält.
+  `"authorization": <Object>`: Ein Objekt, das die für die Autorisierung erforderlichen Felder enthält.

### Autorisierungsobjekt für die Abonnementregistrierung
<a name="authorization-object-for-subscription-registration"></a>

Für das Autorisierungsobjekt gelten dieselben Regeln wie im [Das Format der Header-Parameter basiert auf dem AWS AppSync API-Autorisierungsmodus](#header-parameter-format-based-on-appsync-api-authorization-mode) Abschnitt. Die einzige Ausnahme ist IAM, wo sich die SigV4-Signaturinformationen geringfügig unterscheiden. Weitere Details finden Sie im IAM-Beispiel.

Beispiel mit Verwendung von Amazon Cognito-Benutzerpools:

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

Beispiel mit Verwendung von 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"
}
```

Beispiel mit einem benutzerdefinierten Domainnamen:

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

Die SigV4-Signatur muss nicht `/connect` an die URL angehängt werden, und die stringifizierte JSON-GraphQL-Operation ersetzt sie. `data` Im Folgenden finden Sie ein Beispiel für eine SigV4-Signaturanforderung:

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

## Bestätigungsnachricht für das Abonnement
<a name="subscription-acknowledge-message"></a>

Nach dem Senden der Abonnementstartnachricht sollte der Client warten, AWS AppSync bis die Nachricht gesendet wird`start_ack`. Die `start_ack` Nachricht weist darauf hin, dass das Abonnement erfolgreich ist.

Beispiel für eine Abonnementbestätigung:

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

## Fehlermeldung
<a name="error-message"></a>

Wenn der Verbindungsaufbau oder die Abonnementregistrierung fehlschlägt oder wenn ein Abonnement vom Server aus beendet wird, sendet der Server eine Fehlermeldung an den Client. Tritt der Fehler während der Verbindungsinitialisierung auf, wird die Verbindung vom Server geschlossen.
+  `"type": "error"`: Ein konstanter `<string>`-Parameter.
+  `"id": <string>`: Die ID des entsprechenden registrierten Abonnements, falls relevant.
+  `"payload" <Object>`: Ein Objekt, das die entsprechenden Fehlerinformationen enthält.

Beispiel:

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

## Verarbeitung von Datennachrichten
<a name="processing-data-messages"></a>

Wenn ein Client eine Mutation einreicht, AWS AppSync identifiziert er alle Abonnenten, die daran interessiert sind, und sendet eine `"type":"data"` Nachricht an jeden, der das entsprechende Abonnement `id` aus dem `"start"` Abonnementvorgang verwendet. Es wird erwartet, `id` dass der Client den Überblick über das von ihm gesendete Abonnement behält, sodass der Client, wenn er eine Datennachricht empfängt, diese dem entsprechenden Abonnement zuordnen kann.
+  `"type": "data"`: Ein konstanter `<string>`-Parameter.
+  `"id": <string>`: Die ID des entsprechenden registrierten Abonnements.
+  `"payload" <Object>`: Ein Objekt, das die Abonnementinformationen enthält.

Beispiel:

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

## Nachricht über die Aufhebung der Abonnementregistrierung
<a name="subscription-unregistration-message"></a>

Wenn die App die Abonnementereignisse nicht mehr abhören möchte, sollte der Client eine Nachricht mit dem folgenden stringifizierten JSON-Objekt senden:
+  `"type": "stop"`: Ein konstanter `<string>`-Parameter.
+  `"id": <string>`: Die ID des Abonnements, für das die Registrierung aufgehoben werden soll.

Beispiel:

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

AWS AppSync sendet eine Bestätigungsnachricht mit dem folgenden stringifizierten JSON-Objekt zurück:
+  `"type": "complete"`: Ein konstanter `<string>`-Parameter.
+  `"id": <string>`: Die ID des nicht registrierten Abonnements.

Nachdem der Client die Bestätigungsnachricht erhalten hat, erhält er keine weiteren Nachrichten für dieses spezielle Abonnement.

Beispiel:

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

## Trennen der Verbindung WebSocket
<a name="disconnecting-the-websocket"></a>

Um Datenverlust zu vermeiden, sollte der Client vor dem Trennen der Verbindung über die erforderliche Logik verfügen, um zu überprüfen, ob derzeit kein Vorgang über die WebSocket Verbindung ausgeführt wird. Vor dem Trennen der Verbindung mit dem sollten alle Abonnements abgemeldet werden. WebSocket