

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.

# Verwenden von Delta Sync-Vorgängen für versionierte Datenquellen in AWS AppSync
<a name="tutorial-delta-sync"></a>

**Anmerkung**  
Wir unterstützen jetzt hauptsächlich die APPSYNC\$1JS-Laufzeit und ihre Dokumentation. [Bitte erwägen Sie, die APPSYNC\$1JS-Laufzeit und ihre Anleitungen hier zu verwenden.](https://docs.aws.amazon.com/appsync/latest/devguide/tutorials-js.html)

Client-Anwendungen AWS AppSync speichern Daten, indem sie GraphQL-Antworten lokal auf der Festplatte in einer mobile/web Anwendung zwischenspeichern. Versionierte Datenquellen und `Sync`-Vorgänge bieten Kunden die Möglichkeit, den Synchronisierungsprozess mit einem einzigen Resolver durchzuführen. Auf diese Weise können Clients ihren lokalen Cache mit Ergebnissen aus einer Basis-Abfrage, die möglicherweise viele Datensätze enthalten, hydratisieren und anschließend nur die Daten empfangen, die seit der letzten Abfrage geändert wurden (die *Delta-Updates*). Indem Clients berechtigt werden, die Basis-Hydration des Caches mit einer Abfrage und inkrementelle Updates mit einer anderen Abfrage separat durchzuführen, können die Rechenvorgänge von der Client-Anwendung in das Backend verlagert werden. Dies ist wesentlich effizienter für Client-Anwendungen, die häufig zwischen Online- und Offline-Status wechseln.

Um Delta Sync zu implementieren, verwendet die `Sync`-Abfrage den `Sync`-Vorgang für eine versionierte Datenquelle. Wenn eine AWS AppSync Mutation ein Element in einer versionierten Datenquelle ändert, wird ein Datensatz dieser Änderung ebenfalls in der *Delta-Tabelle* gespeichert. Sie können wählen, ob Sie verschiedene *Delta-Tabellen* (z. B. eine pro Typ, eine pro Domainbereich) für andere versionierte Datenquellen oder eine einzelne *Delta-Tabelle* für Ihre API verwenden möchten. AWS AppSync empfiehlt, keine einzige *Delta-Tabelle* für mehrere APIs zu verwenden, um die Kollision von Primärschlüsseln zu vermeiden.

Darüber hinaus können Delta Sync-Clients auch ein Abonnement als Argument erhalten. Der Client koordiniert dann das Wiederherstellen von Abonnementverbindungen und Schreibvorgänge während des Übergangs vom Offline- zum Online-Zustand. Delta Sync führt hierzu eine automatische Wiederaufnahme der Abonnements durch, einschließlich exponentiellem Backoff und Neuversuch mit Jitter in verschiedenen Netzwerkfehlerszenarien und Speichern der Ereignisse in einer Warteschlange. Die entsprechende Delta- oder Basisabfrage wird dann ausgeführt, bevor Ereignisse aus der Warteschlange zusammengeführt und letztlich Abonnements wie gewohnt verarbeitet werden.

Die Dokumentation zu den Client-Konfigurationsoptionen, einschließlich Amplify DataStore, ist auf der [Amplify Framework-Website](https://aws-amplify.github.io/) verfügbar. In dieser Dokumentation wird beschrieben, wie Sie versionierte DynamoDB-Datenquellen und `Sync`-Vorgänge so einrichten, dass sie mit dem Delta Sync-Client für optimalen Datenzugriff arbeiten.

## One-Click-Setup
<a name="one-click-setup"></a>

Verwenden Sie diese Vorlage, um den GraphQL-Endpunkt AWS AppSync mit allen konfigurierten Resolvern und den erforderlichen AWS Ressourcen automatisch einzurichten: AWS CloudFormation 

[https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?templateURL=https://s3.us-west-2.amazonaws.com/awsappsync/resources/deltasync/deltasync-v2-full.yaml](https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?templateURL=https://s3.us-west-2.amazonaws.com/awsappsync/resources/deltasync/deltasync-v2-full.yaml) 

Dieser Stack erstellt die folgenden Ressourcen in Ihrem Konto:
+ 2 DynamoDB-Tabellen (Base und Delta)
+ 1 AWS AppSync API mit API-Schlüssel
+ 1 IAM-Rolle mit Richtlinie für DynamoDB-Tabellen

Es werden zwei Tabellen verwendet, um Ihre Sync-Abfragen in eine zweite Tabelle zu partitionieren, die als Journal der Ereignisse fungiert, welche verpasst wurden, während die Clients offline waren. Um die Abfragen in der Delta-Tabelle effizient zu halten, TTLs werden [Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html) verwendet, um die Ereignisse bei Bedarf automatisch zu bereinigen. Die TTL-Zeit ist für Ihre Anforderungen an die Datenquelle konfigurierbar (Sie können dies als 1 Stunde, 1 Tag usw. verwenden).

## Schema
<a name="schema"></a>

Um Delta Sync zu demonstrieren, erstellt die Beispielanwendung ein *Posts-Schema*, das von einer *Base* - und *Delta-Tabelle* in DynamoDB unterstützt wird. AWS AppSync schreibt die Mutationen automatisch in beide Tabellen. Die Sync-Abfrage ruft Datensätze entsprechend aus der *Basis*- oder der *Delta*-Tabelle ab. Außerdem ist ein einziges Abonnement definiert, das zeigt, wie die Clients dies in ihrer Logik für erneute Verbindungen nutzen können.

```
input CreatePostInput {
    author: String!
    title: String!
    content: String!
    url: String
    ups: Int
    downs: Int
    _version: Int
}

interface Connection {
  nextToken: String
  startedAt: AWSTimestamp!
}

type Mutation {
    createPost(input: CreatePostInput!): Post
    updatePost(input: UpdatePostInput!): Post
    deletePost(input: DeletePostInput!): Post
}

type Post {
    id: ID!
    author: String!
    title: String!
    content: String!
    url: AWSURL
    ups: Int
    downs: Int
    _version: Int
    _deleted: Boolean
    _lastChangedAt: AWSTimestamp!
}

type PostConnection implements Connection {
    items: [Post!]!
    nextToken: String
    startedAt: AWSTimestamp!
}

type Query {
    getPost(id: ID!): Post
    syncPosts(limit: Int, nextToken: String, lastSync: AWSTimestamp): PostConnection!
}

type Subscription {
    onCreatePost: Post
        @aws_subscribe(mutations: ["createPost"])
    onUpdatePost: Post
        @aws_subscribe(mutations: ["updatePost"])
    onDeletePost: Post
        @aws_subscribe(mutations: ["deletePost"])
}

input DeletePostInput {
    id: ID!
    _version: Int!
}

input UpdatePostInput {
    id: ID!
    author: String
    title: String
    content: String
    url: String
    ups: Int
    downs: Int
    _version: Int!
}

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

Das GraphQL-Schema ist Standard. Einige Aspekte sind jedoch der Erwähnung wert, bevor Sie fortfahren. Zuerst werden alle Mutationen automatisch in die *Basis*-Tabelle und dann in die *Delta*-Tabelle geschrieben. Die *Basis*-Tabelle ist die zentrale Datenquelle (Single Source of Truth) für den Status, während die *Delta*-Tabelle Ihr Journal ist. Wenn Sie die `lastSync: AWSTimestamp` nicht übergeben, wird die `syncPosts`-Abfrage über die *Basis*-Tabelle ausgeführt. Sie hydratisiert den Cache und wird regelmäßig als *globaler Catchup-Prozess* für Sonderfälle ausgeführt, in denen Clients länger als die in der *Delta*-Tabelle konfigurierte TTL-Zeit offline sind. Wenn Sie die `lastSync: AWSTimestamp`-Abfrage jedoch übergeben, wird die `syncPosts`-Abfrage über die *Delta*-Tabelle ausgeführt und von Clients verwendet, um Ereignisse abzurufen, die seit ihrem letzte Offline-Zeitpunkt geändert wurden. Amplify-Clients übergeben den `lastSync: AWSTimestamp`-Wert automatisch und halten ihn entsprechend dauerhaft auf der Festplatte.

Das Feld *\$1deleted* auf *Post* wird für **DELETE**-Vorgänge verwendet. Wenn Clients offline sind und Datensätze aus der *Basis*-Tabelle entfernt werden, benachrichtigt dieses Attribut Clients, die eine Synchronisierung durchführen, dass sie Elemente aus ihrem lokalen Cache entfernen müssen. In Fällen, in denen Clients für längere Zeiträume offline sind und das Element entfernt wurde, bevor der Client diesen Wert mit einer Delta Sync-Abfrage abrufen kann, wird das globale Catchup-Ereignis in der Basis-Abfrage (im Client konfigurierbar) ausgeführt und entfernt das Element aus dem Cache. Dieses Feld ist als optional gekennzeichnet, weil es nur dann einen Wert zurückgibt, wenn es eine Sync-Abfrage ausführt, in der gelöschte Elemente vorhanden sind.

## Mutationen
<a name="mutations"></a>

 AWS AppSync Führt für alle Mutationen eine Create/Update/Delete Standardoperation in der *Basistabelle* aus und zeichnet die Änderung auch automatisch in der *Delta-Tabelle* auf. Sie können den Aufbewahrungszeitraum für Datensätze verlängern oder verkürzen, indem Sie den `DeltaSyncTableTTL`-Wert in der Datenquelle anpassen. Für Unternehmen, deren Daten häufigen Änderungen unterliegen, ist es sinnvoll, einen kurzen Zeitraum anzugeben. Wenn Ihre Clients für längere Zeiträume offline sind, kann es ratsam sein, einen längeren Zeitraum anzugeben.

## Sync-Abfragen
<a name="sync-queries"></a>

Die *Basisabfrage* ist ein DynamoDB-Synchronisierungsvorgang ohne Angabe eines `lastSync` Werts. Dies funktioniert in vielen Organisationen, weil die Basis-Abfrage nur beim Start und danach in regelmäßigen Abständen ausgeführt wird.

Die *Deltaabfrage* ist ein DynamoDB-Synchronisierungsvorgang mit einem angegebenen `lastSync` Wert. Die *Delta-Abfrage* wird jedes Mal ausgeführt, wenn der Client wieder in den Online-Zustand wechselt (sofern nicht die periodische Basis-Abfrage die Ausführung ausgelöst hat). Clients verfolgen automatisch das letzte Mal nach, als sie eine Abfrage zum Synchronisieren von Daten erfolgreich ausgeführt haben.

Wenn eine Delta-Abfrage ausgeführt wird, verwendet der Resolver der Abfrage `ds_pk` und `ds_sk`, um nur die Datensätze abzufragen, die seit der letzten Synchronisierung durch den Client geändert wurden. Der Client speichert die entsprechende GraphQL-Antwort.

Weitere Informationen zum Ausführen von Sync-Abfragen finden Sie in der [Dokumentation zu Synchronisierungsoperationen](aws-appsync-conflict-detection-and-sync-sync-operations.md).

## Beispiel
<a name="example"></a>

Beginnen wir zunächst mit dem Aufruf einer `createPost`-Mutation, um ein Element zu erstellen:

```
mutation create {
  createPost(input: {author: "Nadia", title: "My First Post", content: "Hello World"}) {
    id
    author
    title
    content
    _version
    _lastChangedAt
    _deleted
  }
}
```

Der Rückgabewert dieser Mutation sieht wie folgt aus:

```
{
  "data": {
    "createPost": {
      "id": "81d36bbb-1579-4efe-92b8-2e3f679f628b",
      "author": "Nadia",
      "title": "My First Post",
      "content": "Hello World",
      "_version": 1,
      "_lastChangedAt": 1574469356331,
      "_deleted": null
    }
  }
}
```

Wenn Sie den Inhalt der *Basis*-Tabelle untersuchen, wird ein Datensatz angezeigt, der wie folgt aussieht:

```
{
  "_lastChangedAt": {
    "N": "1574469356331"
  },
  "_version": {
    "N": "1"
  },
  "author": {
    "S": "Nadia"
  },
  "content": {
    "S": "Hello World"
  },
  "id": {
    "S": "81d36bbb-1579-4efe-92b8-2e3f679f628b"
  },
  "title": {
    "S": "My First Post"
  }
}
```

Wenn Sie den Inhalt der *Delta*-Tabelle untersuchen, wird ein Datensatz angezeigt, der wie folgt aussieht:

```
{
  "_lastChangedAt": {
    "N": "1574469356331"
  },
  "_ttl": {
    "N": "1574472956"
  },
  "_version": {
    "N": "1"
  },
  "author": {
    "S": "Nadia"
  },
  "content": {
    "S": "Hello World"
  },
  "ds_pk": {
    "S": "AppSync-delta-sync-post:2019-11-23"
  },
  "ds_sk": {
    "S": "00:35:56.331:81d36bbb-1579-4efe-92b8-2e3f679f628b:1"
  },
  "id": {
    "S": "81d36bbb-1579-4efe-92b8-2e3f679f628b"
  },
  "title": {
    "S": "My First Post"
  }
}
```

Jetzt können wir eine *Basis*-Abfrage simulieren, die von einem Client ausgeführt wird, um seinen lokalen Datenspeicher mit einer `syncPosts`-Abfrage zu hydratisieren, die wie folgt aussieht:

```
query baseQuery {
  syncPosts(limit: 100, lastSync: null, nextToken: null) {
    items {
      id
      author
      title
      content
      _version
      _lastChangedAt
    }
    startedAt
    nextToken
  }
}
```

Der Rückgabewert dieser *Basis*-Abfrage sieht wie folgt aus:

```
{
  "data": {
    "syncPosts": {
      "items": [
        {
          "id": "81d36bbb-1579-4efe-92b8-2e3f679f628b",
          "author": "Nadia",
          "title": "My First Post",
          "content": "Hello World",
          "_version": 1,
          "_lastChangedAt": 1574469356331
        }
      ],
      "startedAt": 1574469602238,
      "nextToken": null
    }
  }
}
```

Wir speichern den `startedAt`-Wert später, um eine *Delta*-Abfrage zu simulieren, aber zuerst müssen wir eine Änderung an unserer Tabelle vornehmen. Verwenden wir die `updatePost`-Mutation zum Ändern unseres vorhandenen Beitrags:

```
mutation updatePost {
  updatePost(input: {id: "81d36bbb-1579-4efe-92b8-2e3f679f628b", _version: 1, title: "Actually this is my Second Post"}) {
    id
    author
    title
    content
    _version
    _lastChangedAt
    _deleted
  }
}
```

Der Rückgabewert dieser Mutation sieht wie folgt aus:

```
{
  "data": {
    "updatePost": {
      "id": "81d36bbb-1579-4efe-92b8-2e3f679f628b",
      "author": "Nadia",
      "title": "Actually this is my Second Post",
      "content": "Hello World",
      "_version": 2,
      "_lastChangedAt": 1574469851417,
      "_deleted": null
    }
  }
}
```

Wenn Sie den Inhalt der *Basis*-Tabelle jetzt untersuchen, sollten Sie das aktualisierte Element sehen:

```
{
  "_lastChangedAt": {
    "N": "1574469851417"
  },
  "_version": {
    "N": "2"
  },
  "author": {
    "S": "Nadia"
  },
  "content": {
    "S": "Hello World"
  },
  "id": {
    "S": "81d36bbb-1579-4efe-92b8-2e3f679f628b"
  },
  "title": {
    "S": "Actually this is my Second Post"
  }
}
```

Wenn Sie den Inhalt der *Delta*-Tabelle jetzt untersuchen, sollten Sie zwei Datensätze sehen:

1. Ein Datensatz zum Zeitpunkt der Erstellung des Elements

1. Ein Datensatz zum Zeitpunkt der Aktualisierung des Elements.

Das neue Element sieht folgendermaßen aus:

```
{
  "_lastChangedAt": {
    "N": "1574469851417"
  },
  "_ttl": {
    "N": "1574473451"
  },
  "_version": {
    "N": "2"
  },
  "author": {
    "S": "Nadia"
  },
  "content": {
    "S": "Hello World"
  },
  "ds_pk": {
    "S": "AppSync-delta-sync-post:2019-11-23"
  },
  "ds_sk": {
    "S": "00:44:11.417:81d36bbb-1579-4efe-92b8-2e3f679f628b:2"
  },
  "id": {
    "S": "81d36bbb-1579-4efe-92b8-2e3f679f628b"
  },
  "title": {
    "S": "Actually this is my Second Post"
  }
}
```

Jetzt können wir eine *Delta*-Abfrage simulieren, um Änderungen abzurufen, die aufgetreten sind, als ein Client offline war. Wir verwenden den `startedAt`-Wert, der von unserer *Basis*-Abfrage zurückgegeben wird, um folgende Anfrage zu stellen:

```
query delta {
  syncPosts(limit: 100, lastSync: 1574469602238, nextToken: null) {
    items {
      id
      author
      title
      content
      _version
    }
    startedAt
    nextToken
  }
}
```

Der Rückgabewert dieser *Delta*-Abfrage sieht wie folgt aus:

```
{
  "data": {
    "syncPosts": {
      "items": [
        {
          "id": "81d36bbb-1579-4efe-92b8-2e3f679f628b",
          "author": "Nadia",
          "title": "Actually this is my Second Post",
          "content": "Hello World",
          "_version": 2
        }
      ],
      "startedAt": 1574470400808,
      "nextToken": null
    }
  }
}
```