

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 DynamoDB-Batchoperationen in AWS AppSync
<a name="tutorial-dynamodb-batch"></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)

AWS AppSync unterstützt die Verwendung von Amazon DynamoDB-Batchoperationen für eine oder mehrere Tabellen in einer einzigen Region. Zu den unterstützten Vorgängen gehören `BatchGetItem`, `BatchPutItem` und `BatchDeleteItem`. Durch die Verwendung dieser Funktionen in AWS AppSync können Sie beispielsweise folgende Aufgaben ausführen:
+ Übermitteln einer Liste von Schlüsseln in einer einzigen Abfrage und Zurückgabe der Ergebnisse aus einer Tabelle
+ Lesen der Datensätze aus einer oder mehrerer Tabellen in einer einzigen Abfrage
+ Schreiben von Datensätzen in großen Mengen in einer oder mehreren Tabellen
+ Bedingtes Schreiben oder Löschen von Datensätzen in mehreren Tabellen, zwischen denen möglicherweise eine Beziehung besteht

Die Verwendung von Batch-Operationen mit DynamoDB AWS AppSync ist eine fortgeschrittene Technik, die etwas mehr Nachdenken und Wissen über Ihre Backend-Operationen und Tabellenstrukturen erfordert. Darüber hinaus AWS AppSync weisen Batch-Operationen zwei wesentliche Unterschiede zu Vorgängen ohne Batch auf:
+ Die Rolle der Datenquelle muss über Berechtigungen für alle Tabellen verfügen, auf die Resolver zugreifen wird.
+ Die Tabellenangaben für einen Resolver sind Teil der Zuweisungsvorlage.

## Berechtigungen
<a name="permissions"></a>

Wie bei anderen Resolvern müssen Sie eine Datenquelle in erstellen AWS AppSync und entweder eine Rolle erstellen oder eine vorhandene verwenden. Da Batchoperationen unterschiedliche Berechtigungen für DynamoDB-Tabellen erfordern, müssen Sie den konfigurierten Rollen Berechtigungen für Lese- oder Schreibaktionen gewähren:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": [
                "dynamodb:BatchGetItem",
                "dynamodb:BatchWriteItem"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:dynamodb:us-east-1:111122223333:table/TABLENAME",
                "arn:aws:dynamodb:us-east-1:111122223333:table/TABLENAME/*"
            ]
        }
    ]
}
```

------

 **Hinweis**: Rollen sind an Datenquellen in einer Datenquelle gebunden AWS AppSync, und Resolver für Felder werden für eine Datenquelle aufgerufen. Für Datenquellen, die für den Abruf von DynamoDB konfiguriert sind, ist nur eine Tabelle angegeben, um die Konfiguration zu vereinfachen. Möchten Sie jedoch einen Stapelvorgang an mehreren Tabellen mit nur einem Resolver ausführen, stellt dies eine erweiterte Aufgabe dar und Sie müssen der Rolle dieser Datenquelle Zugriff auf alle Tabellen gewähren, mit denen der Resolver interagieren wird. Dies kann im Feld **Ressource (Resource)** in der IAM-Richtlinie weiter oben eingerichtet werden. Die Konfiguration der Tabellen, um Stapelaufrufe auszuführen, erfolgt in der Resolver-Vorlage und wird nachfolgend beschrieben.

## Datenquelle
<a name="data-source"></a>

Der Einfachheit halber verwenden wir die gleiche Datenquelle für alle in diesem Tutorial verwendeten Resolver. Erstellen Sie auf der Registerkarte **Datenquellen** eine neue DynamoDB-Datenquelle und geben Sie ihr einen Namen. **BatchTutorial** Sie können den Namen der Tabelle frei wählen, da Tabellennamen als Teil der Zuweisungsvorlage für Anforderungen bei Stapelvorgängen angegeben werden. Wir geben der Tabelle den Namen `empty`.

Für diese Anleitung kann jede Rolle mit der folgenden eingebundene Richtlinie verwendet werden:

## Stapelvorgang mit einer Tabelle
<a name="single-table-batch"></a>

**Warnung**  
`BatchPutItem`und `BatchDeleteItem` werden nicht unterstützt, wenn sie zusammen mit der Konflikterkennung und -lösung verwendet werden. Diese Einstellungen müssen deaktiviert werden, um mögliche Fehler zu vermeiden.

In diesem Beispiel gehen wir davon aus, dass Sie über eine einzelne Tabelle mit dem Namen **Posts** verfügen, zu der Sie anhand von Stapelvorgängen Elemente hinzufügen bzw. von der Sie Elemente entfernen möchten. Verwenden Sie das folgende Schema und beachten Sie, dass wir für die Abfrage eine Liste mit folgenden Elementen übergeben IDs:

```
type Post {
    id: ID!
    title: String
}

input PostInput {
    id: ID!
    title: String
}

type Query {
    batchGet(ids: [ID]): [Post]
}

type Mutation {
    batchAdd(posts: [PostInput]): [Post]
    batchDelete(ids: [ID]): [Post]
}

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

Fügen Sie dem Feld `batchAdd()` mithilfe der folgenden **Zuweisungsvorlage für Anforderungen** einen Resolver an. Hierdurch wird automatisch jedes Element im GraphQL- `input PostInput`-Typ berücksichtigt und eine Zuordnung erstellt, wie sie für die `BatchPutItem`-Operation erforderlich ist:

```
#set($postsdata = [])
#foreach($item in ${ctx.args.posts})
    $util.qr($postsdata.add($util.dynamodb.toMapValues($item)))
#end

{
    "version" : "2018-05-29",
    "operation" : "BatchPutItem",
    "tables" : {
        "Posts": $utils.toJson($postsdata)
    }
}
```

In diesem Fall handelt es sich bei der **Zuweisungsvorlage für Antworten** um einen einfachen Pass-Through. Beachten Sie jedoch, dass der Tabellenname als `..data.Posts` an das Kontextobjekt angefügt wird:

```
$util.toJson($ctx.result.data.Posts)
```

Navigieren Sie jetzt zur Seite **Queries (Abfragen)** der AWS AppSync-Konsole und führen Sie die folgende **batchAdd**-Mutation aus:

```
mutation add {
    batchAdd(posts:[{
            id: 1 title: "Running in the Park"},{
            id: 2 title: "Playing fetch"
        }]){
            id
            title
    }
}
```

Sie sollten die Ergebnisse auf dem Bildschirm sehen und können unabhängig voneinander über die DynamoDB-Konsole überprüfen, ob beide Werte in die Tabelle **Posts** geschrieben wurden.

Fügen Sie als Nächstes dem Feld `batchGet()` mithilfe der folgenden **Zuweisungsvorlage für Anforderungen** einen Resolver an. Hierdurch wird automatisch jedes Element im GraphQL `ids:[]`-Typ berücksichtigt und eine Zuordnung erstellt, wie sie für die `BatchGetItem`-Operation erforderlich ist:

```
#set($ids = [])
#foreach($id in ${ctx.args.ids})
    #set($map = {})
    $util.qr($map.put("id", $util.dynamodb.toString($id)))
    $util.qr($ids.add($map))
#end

{
    "version" : "2018-05-29",
    "operation" : "BatchGetItem",
    "tables" : {
        "Posts": {
            "keys": $util.toJson($ids),
            "consistentRead": true,
            "projection" : {
                "expression" : "#id, title",
                "expressionNames" : { "#id" : "id"}
                }
        }
    }
}
```

In diesem Fall handelt es sich bei der **Zuweisungsvorlage für Anforderungen** wiederum um einen einfachen Pass-Through, dem erneut dem Context-Objekt des Tabellennamens `..data.Posts` angefügt wurde:

```
$util.toJson($ctx.result.data.Posts)
```

Navigieren Sie wieder zur Seite **Queries (Abfragen)** der AWS AppSync-Konsole und führen Sie die folgende **batchGet-Abfrage** aus:

```
query get {
    batchGet(ids:[1,2,3]){
        id
        title
    }
}
```

Dies sollte die Ergebnisse für die beiden `id`-Werte, die Sie zuvor hinzugefügt haben, zurückgeben. Beachten Sie, dass ein `null`-Wert für die `id` mit einem Wert von `3` zurückgegeben wurde. Das liegt daran, dass bisher noch kein Datensatz mit diesem Wert in Ihrer **Posts**-Tabelle vorhanden war. Beachten Sie auch, dass die Ergebnisse in derselben Reihenfolge AWS AppSync zurückgegeben werden wie die an die Abfrage übergebenen Schlüssel. Dies ist eine zusätzliche Funktion, die in Ihrem AWS AppSync Namen ausgeführt wird. Wenn Sie jetzt zu `batchGet(ids:[1,3,2)` wechseln, sehen Sie, dass sich die Reihenfolge geändert hat. Sie können darüber hinaus erkennen, welche `id` einen `null`-Wert zurückgegeben hat.

Fügen Sie zum Schluss dem Feld `batchDelete()` mithilfe der folgenden **Zuweisungsvorlage für Anforderungen** einen Resolver an. Hierdurch wird automatisch jedes Element im GraphQL `ids:[]`-Typ berücksichtigt und eine Zuordnung erstellt, wie sie für die `BatchGetItem`-Operation erforderlich ist:

```
#set($ids = [])
#foreach($id in ${ctx.args.ids})
    #set($map = {})
    $util.qr($map.put("id", $util.dynamodb.toString($id)))
    $util.qr($ids.add($map))
#end

{
    "version" : "2018-05-29",
    "operation" : "BatchDeleteItem",
    "tables" : {
        "Posts": $util.toJson($ids)
    }
}
```

In diesem Fall handelt es sich bei der **Zuweisungsvorlage für Anforderungen** wiederum um einen einfachen Pass-Through, dem erneut dem Context-Objekt des Tabellennamens `..data.Posts` angefügt wurde:

```
$util.toJson($ctx.result.data.Posts)
```

Navigieren Sie jetzt zurück zur Seite **Queries (Abfragen)** der AWS AppSync-Konsole und führen Sie die folgende **batchDelete**-Mutation aus:

```
mutation delete {
    batchDelete(ids:[1,2]){ id }
}
```

Die Datensätze mit der `id` `1` und `2` sollten jetzt gelöscht sein. Wenn Sie die frühere `batchGet()`-Abfrage ausführen, sollten diese `null` zurückgeben.

## Stapelvorgang mit mehreren Tabellen
<a name="multi-table-batch"></a>

**Warnung**  
`BatchPutItem`und `BatchDeleteItem` werden nicht unterstützt, wenn sie zusammen mit der Konflikterkennung und -lösung verwendet werden. Diese Einstellungen müssen deaktiviert werden, um mögliche Fehler zu vermeiden.

AWS AppSync ermöglicht es Ihnen auch, tabellenübergreifende Batch-Operationen durchzuführen. Lassen Sie uns hierzu eine komplexere Anwendung erstellen. Stellen Sie sich vor, wir entwickeln eine Gesundheits-App für Haustiere, bei der Sensoren den Standort und die Körpertemperatur der Tiere aufzeichnen. Diese Sensoren sind batteriebetrieben und versuchen, alle paar Minuten eine Verbindung mit dem Netzwerk aufzubauen. Wenn ein Sensor eine Verbindung herstellt, sendet er seine Messwerte an unsere AWS AppSync API. Die Daten werden von Auslösern analysiert und dem Besitzer des Haustiers in einem Dashboard angezeigt. Lassen Sie uns jetzt die Interaktionen zwischen dem Sensor und dem Backend-Datenspeicher näher untersuchen.

Als Voraussetzung erstellen wir zunächst zwei DynamoDB-Tabellen. LocationReadings speichert **Sensorstandortwerte** und **TemperatureReadings speichert Sensortemperaturwerte**. Beide Tabellen haben zufällig die gleiche Primärschlüsselstruktur: `sensorId (String)` als der Partitionsschlüssel und `timestamp (String)` als der Sortierschlüssel.

Verwenden wir das folgende GraphQL-Schema:

```
type Mutation {
    # Register a batch of readings
    recordReadings(tempReadings: [TemperatureReadingInput], locReadings: [LocationReadingInput]): RecordResult
    # Delete a batch of readings
    deleteReadings(tempReadings: [TemperatureReadingInput], locReadings: [LocationReadingInput]): RecordResult
}

type Query {
    # Retrieve all possible readings recorded by a sensor at a specific time
    getReadings(sensorId: ID!, timestamp: String!): [SensorReading]
}

type RecordResult {
    temperatureReadings: [TemperatureReading]
    locationReadings: [LocationReading]
}

interface SensorReading {
    sensorId: ID!
    timestamp: String!
}

# Sensor reading representing the sensor temperature (in Fahrenheit)
type TemperatureReading implements SensorReading {
    sensorId: ID!
    timestamp: String!
    value: Float
}

# Sensor reading representing the sensor location (lat,long)
type LocationReading implements SensorReading {
    sensorId: ID!
    timestamp: String!
    lat: Float
    long: Float
}

input TemperatureReadingInput {
    sensorId: ID!
    timestamp: String
    value: Float
}

input LocationReadingInput {
    sensorId: ID!
    timestamp: String
    lat: Float
    long: Float
}
```

### BatchPutItem - Aufzeichnen von Sensormesswerten
<a name="batchputitem-recording-sensor-readings"></a>

Nachdem eine Verbindung zum Internet hergestellt wurde, müssen unsere Sensoren in der Lage sein, ihre Messwerte zu senden. Sie verwenden dazu die API GraphQL-Feld `Mutation.recordReadings`. Um unsere API in Betrieb nehmen zu können, müssen wir zunächst einen Resolver anfügen.

Wählen Sie hierzu **Anfügen (Attach)** neben dem Feld `Mutation.recordReadings` aus. Wählen Sie auf dem nächsten Bildschirm die gleiche `BatchTutorial`-Datenquelle wie zu Beginn dieser Anleitung aus.

Fügen Sie die folgende Zuweisungsvorlage für Anforderungen hinzu.

 **Zuweisungsvorlage für Anforderungen** 

```
## Convert tempReadings arguments to DynamoDB objects
#set($tempReadings = [])
#foreach($reading in ${ctx.args.tempReadings})
    $util.qr($tempReadings.add($util.dynamodb.toMapValues($reading)))
#end

## Convert locReadings arguments to DynamoDB objects
#set($locReadings = [])
#foreach($reading in ${ctx.args.locReadings})
    $util.qr($locReadings.add($util.dynamodb.toMapValues($reading)))
#end

{
    "version" : "2018-05-29",
    "operation" : "BatchPutItem",
    "tables" : {
        "locationReadings": $utils.toJson($locReadings),
        "temperatureReadings": $utils.toJson($tempReadings)
    }
}
```

Wie Sie sehen, können wir über die `BatchPutItem`-Operation mehrere Tabellen angeben.

Verwenden Sie die folgende Zuweisungsvorlage für Antworten.

 **Zuweisungsvorlage für Antworten** 

```
## If there was an error with the invocation
## there might have been partial results
#if($ctx.error)
    ## Append a GraphQL error for that field in the GraphQL response
    $utils.appendError($ctx.error.message, $ctx.error.message)
#end
## Also returns data for the field in the GraphQL response
$utils.toJson($ctx.result.data)
```

Bei Stapelvorgängen können durch den Aufruf sowohl Fehler als auch Ergebnisse zurückgegeben werden. In diesem Fall können wir eine zusätzliche Fehlerbehandlung vornehmen.

 **Hinweis**: Die Verwendung von `$utils.appendError()` lässt sich mit `$util.error()` vergleichen, mit dem großen Unterschied, dass die Bewertung der Zuweisungsvorlage nicht unterbrochen wird. Stattdessen wird signalisiert, dass das Feld zwar eine Fehlermeldung hervorrief, die Beurteilung der Vorlage jedoch abgeschlossen wurde und infolgedessen die Daten wieder an den Aufrufer zurückgegeben werden konnten. Wir empfehlen Ihnen die Verwendung von `$utils.appendError()`, wenn Ihrer Anwendung zumindest Teilergebnisse zurückgegeben werden müssen.

Speichern Sie den Resolver und navigieren Sie zur **Abfrageseite** der AWS AppSync Konsole. Senden wir jetzt einige Sensormesswerte.

Führen Sie die folgende Mutation aus:

```
mutation sendReadings {
  recordReadings(
    tempReadings: [
      {sensorId: 1, value: 85.5, timestamp: "2018-02-01T17:21:05.000+08:00"},
      {sensorId: 1, value: 85.7, timestamp: "2018-02-01T17:21:06.000+08:00"},
      {sensorId: 1, value: 85.8, timestamp: "2018-02-01T17:21:07.000+08:00"},
      {sensorId: 1, value: 84.2, timestamp: "2018-02-01T17:21:08.000+08:00"},
      {sensorId: 1, value: 81.5, timestamp: "2018-02-01T17:21:09.000+08:00"}
    ]
    locReadings: [
      {sensorId: 1, lat: 47.615063, long: -122.333551, timestamp: "2018-02-01T17:21:05.000+08:00"},
      {sensorId: 1, lat: 47.615163, long: -122.333552, timestamp: "2018-02-01T17:21:06.000+08:00"}
      {sensorId: 1, lat: 47.615263, long: -122.333553, timestamp: "2018-02-01T17:21:07.000+08:00"}
      {sensorId: 1, lat: 47.615363, long: -122.333554, timestamp: "2018-02-01T17:21:08.000+08:00"}
      {sensorId: 1, lat: 47.615463, long: -122.333555, timestamp: "2018-02-01T17:21:09.000+08:00"}
    ]) {
    locationReadings {
      sensorId
      timestamp
      lat
      long
    }
    temperatureReadings {
      sensorId
      timestamp
      value
    }
  }
}
```

Wir werden 10 Sensormesswerte in einer Mutation senden, wobei die Messwerte in zwei Tabellen aufgeteilt sind. **Verwenden Sie die DynamoDB-Konsole, um zu überprüfen, ob Daten sowohl in den **LocationReadings** - als auch in den TemperatureReadings-Tabellen angezeigt werden.**

### BatchDeleteItem - Löschen von Sensormesswerten
<a name="batchdeleteitem-deleting-sensor-readings"></a>

Gleichzeitig müssen wir auch Stapel mit Sensormesswerten löschen können. Dazu verwenden wir das GraphQL-Feld `Mutation.deleteReadings`. Wählen Sie hierzu **Anfügen (Attach)** neben dem Feld `Mutation.recordReadings` aus. Wählen Sie auf dem nächsten Bildschirm die gleiche `BatchTutorial`-Datenquelle wie zu Beginn dieser Anleitung aus.

Verwenden Sie die folgende Zuweisungsvorlage für Anforderungen.

 **Zuweisungsvorlage für Anforderungen** 

```
## Convert tempReadings arguments to DynamoDB primary keys
#set($tempReadings = [])
#foreach($reading in ${ctx.args.tempReadings})
    #set($pkey = {})
    $util.qr($pkey.put("sensorId", $reading.sensorId))
    $util.qr($pkey.put("timestamp", $reading.timestamp))
    $util.qr($tempReadings.add($util.dynamodb.toMapValues($pkey)))
#end

## Convert locReadings arguments to DynamoDB primary keys
#set($locReadings = [])
#foreach($reading in ${ctx.args.locReadings})
    #set($pkey = {})
    $util.qr($pkey.put("sensorId", $reading.sensorId))
    $util.qr($pkey.put("timestamp", $reading.timestamp))
    $util.qr($locReadings.add($util.dynamodb.toMapValues($pkey)))
#end

{
    "version" : "2018-05-29",
    "operation" : "BatchDeleteItem",
    "tables" : {
        "locationReadings": $utils.toJson($locReadings),
        "temperatureReadings": $utils.toJson($tempReadings)
    }
}
```

Die Zuweisungsvorlage für Antworten ist die gleiche, die wir bereits für `Mutation.recordReadings` verwendet haben.

 **Zuweisungsvorlage für Antworten** 

```
## If there was an error with the invocation
## there might have been partial results
#if($ctx.error)
    ## Append a GraphQL error for that field in the GraphQL response
    $utils.appendError($ctx.error.message, $ctx.error.message)
#end
## Also return data for the field in the GraphQL response
$utils.toJson($ctx.result.data)
```

Speichern Sie den Resolver und navigieren Sie zur **Abfrageseite** der AWS AppSync Konsole. Lassen Sie uns jetzt einige der Sensormesswerte löschen\$1

Führen Sie die folgende Mutation aus:

```
mutation deleteReadings {
  # Let's delete the first two readings we recorded
  deleteReadings(
    tempReadings: [{sensorId: 1, timestamp: "2018-02-01T17:21:05.000+08:00"}]
    locReadings: [{sensorId: 1, timestamp: "2018-02-01T17:21:05.000+08:00"}]) {
    locationReadings {
      sensorId
      timestamp
      lat
      long
    }
    temperatureReadings {
      sensorId
      timestamp
      value
    }
  }
}
```

**Überprüfen Sie über die DynamoDB-Konsole, ob diese beiden Messwerte aus den Tabellen **LocationReadings und TemperatureReadings** gelöscht wurden.**

### BatchGetItem - Messwerte abrufen
<a name="batchgetitem-retrieve-readings"></a>

Eine weitere gängige Operation für unsere Gesundheits-App für Haustiere bestünde darin, die Messwerte eines Sensors zu einem bestimmten Zeitpunkt abzurufen. Fügen wir dazu einen Resolver zum GraphQL-Feld `Query.getReadings` unseres Schemas hinzu. Wählen Sie **Anfügen (Attach)** und auf dem nächsten Bildschirm die gleiche `BatchTutorial`-Datenquelle wie zu Beginn dieser Anleitung aus.

Fügen wir die folgende Zuweisungsvorlage für Anforderungen hinzu.

 **Zuweisungsvorlage für Anforderungen** 

```
## Build a single DynamoDB primary key,
## as both locationReadings and tempReadings tables
## share the same primary key structure
#set($pkey = {})
$util.qr($pkey.put("sensorId", $ctx.args.sensorId))
$util.qr($pkey.put("timestamp", $ctx.args.timestamp))

{
    "version" : "2018-05-29",
    "operation" : "BatchGetItem",
    "tables" : {
        "locationReadings": {
            "keys": [$util.dynamodb.toMapValuesJson($pkey)],
            "consistentRead": true
        },
        "temperatureReadings": {
            "keys": [$util.dynamodb.toMapValuesJson($pkey)],
            "consistentRead": true
        }
    }
}
```

Beachten Sie, dass wir die **BatchGetItem**Operation jetzt verwenden.

Unsere Zuweisungsvorlage für Antworten unterscheidet sich etwas, da wir uns für die Rückgabe einer `SensorReading`-Liste entschieden haben. Ordnen wir jetzt das Aufrufergebnis der gewünschten Form zu.

 **Zuweisungsvorlage für Antworten** 

```
## Merge locationReadings and temperatureReadings
## into a single list
## __typename needed as schema uses an interface
#set($sensorReadings = [])

#foreach($locReading in $ctx.result.data.locationReadings)
    $util.qr($locReading.put("__typename", "LocationReading"))
    $util.qr($sensorReadings.add($locReading))
#end

#foreach($tempReading in $ctx.result.data.temperatureReadings)
    $util.qr($tempReading.put("__typename", "TemperatureReading"))
    $util.qr($sensorReadings.add($tempReading))
#end

$util.toJson($sensorReadings)
```

Speichern Sie den Resolver und navigieren Sie zur Seite „**Abfragen**“ der AWS AppSync Konsole. Rufen wir jetzt die Sensormesswerte ab\$1

Führen Sie die folgende Abfrage aus:

```
query getReadingsForSensorAndTime {
  # Let's retrieve the very first two readings
  getReadings(sensorId: 1, timestamp: "2018-02-01T17:21:06.000+08:00") {
    sensorId
    timestamp
    ...on TemperatureReading {
      value
    }
    ...on LocationReading {
      lat
      long
    }
  }
}
```

Wir haben erfolgreich die Verwendung von DynamoDB-Batchoperationen unter Verwendung von demonstriert. AWS AppSync

## Fehlerbehandlung
<a name="error-handling"></a>

In AWS AppSync Datenquellenoperationen können manchmal Teilergebnisse zurückgegeben werden. Wir verwenden den Begriff Teilergebnis, wenn bei der Ausgabe einer Operation einige Daten fehlen und darin ein Fehler enthalten ist. Da die Fehlerbehandlung grundsätzlich anwendungsspezifisch erfolgt, bietet Ihnen AWS AppSync die Möglichkeit, Fehler in der Zuweisungsvorlage für Antworten zu handhaben. Sollte beim Resolver ein Aufruffehler vorliegen, lässt sich dieser im Kontext an `$ctx.error` erkennen. Aufruffehler umfassen immer eine Nachricht und eine Art, auf die über die Eigenschaften `$ctx.error.message` und `$ctx.error.type`zugegriffen werden kann. Während die Zuweisungsvorlagen für Antworten aufgerufen werden, können Sie Teilergebnisse auf drei verschiedene Arten handhaben:

1. Übergehen des Aufruffehlers, indem nur Daten zurückgegeben werden

1. Melden des Fehlers (unter Verwendung von `$util.error(...)`), wodurch die Bewertung der Zuweisungsvorlage für Antworten unterbrochen wird und keine Daten zurückgegeben werden

1. Anfügen eines Fehler (unter Verwendung von `$util.appendError(...)`) und der gleichzeitigen Zurückgabe von Daten

Wir veranschaulichen jetzt jeden der drei oben genannten Punkte mit den DynamoDB-Stapelvorgängen.

### DynamoDB-Stapelvorgänge
<a name="dynamodb-batch-operations"></a>

Mit DynamoDB-Stapelvorgängen ist es möglich, dass ein Stapel teilweise abgeschlossen wird. Das bedeutet, dass einige der angeforderten Elemente oder Schlüssel nicht verarbeitet werden. Wenn AWS AppSync ein Stapel nicht abgeschlossen werden kann, werden unverarbeitete Elemente und ein Aufruffehler für den Kontext angezeigt.

Wir werden die Fehlerbehandlung mithilfe der `Query.getReadings`-Feldkonfiguration der `BatchGetItem`-Operation aus dem vorherigen Abschnitt dieser Anleitung implementieren. Dieses Mal nehmen wir jedoch an, dass bei der Ausführung des `Query.getReadings`-Felds die DynamoDB-Tabelle `temperatureReadings` den bereitgestellten Durchsatz überschritten hat. DynamoDB hat **ProvisionedThroughputExceededException**beim zweiten Versuch a ausgelöst, AWS AppSync um die verbleibenden Elemente im Stapel zu verarbeiten.

Der folgende JSON-Code stellt den serialisierten Kontext dar, nachdem der DynamoDB-Stapel aufgerufen, aber noch bevor die Zuweisungsvorlage für Antworten ausgewertet wurde.

```
{
  "arguments": {
    "sensorId": "1",
    "timestamp": "2018-02-01T17:21:05.000+08:00"
  },
  "source": null,
  "result": {
    "data": {
      "temperatureReadings": [
        null
      ],
      "locationReadings": [
        {
          "lat": 47.615063,
          "long": -122.333551,
          "sensorId": "1",
          "timestamp": "2018-02-01T17:21:05.000+08:00"
        }
      ]
    },
    "unprocessedKeys": {
      "temperatureReadings": [
        {
          "sensorId": "1",
          "timestamp": "2018-02-01T17:21:05.000+08:00"
        }
      ],
      "locationReadings": []
    }
  },
  "error": {
    "type": "DynamoDB:ProvisionedThroughputExceededException",
    "message": "You exceeded your maximum allowed provisioned throughput for a table or for one or more global secondary indexes. (...)"
  },
  "outErrors": []
}
```

Beachten Sie in diesem Kontext die folgenden Dinge:
+ der Aufruffehler wurde für den Kontext bei `$ctx.error` by festgelegt AWS AppSync, und der Fehlertyp wurde auf **DynamoDB**: gesetzt. ProvisionedThroughputExceededException
+ die Ergebnisse werden pro Tabelle unter `$ctx.result.data` zugeordnet, auch wenn ein Fehler vorhanden ist
+ unverarbeitete Schlüssel finden Sie unter `$ctx.result.data.unprocessedKeys`. Hier AWS AppSync konnte das Element mit dem Schlüssel (sensorId:1, timestamp:2018-02-01T 17:21:05.000 \$1 08:00) aufgrund des unzureichenden Tabellendurchsatzes nicht abgerufen werden.

 **Hinweis**: Für `BatchPutItem` gilt `$ctx.result.data.unprocessedItems`. Für `BatchDeleteItem` gilt `$ctx.result.data.unprocessedKeys`.

Sie können mit diesem Fehler auf drei verschiedene Arten umgehen.

#### 1. Übergehen des Aufruffehlers
<a name="swallowing-the-invocation-error"></a>

Wenn Daten ohne Verarbeitung des Aufruffehlers zurückgegeben werden, wird der Fehler effektiv übergangen. Auf diese Weise ist das Ergebnis für das angegebene GraphQL-Feld immer erfolgreich.

Die von uns geschriebene Zuweisungsvorlage für Antworten ist vertraut und konzentriert sich auf die Ergebnisdaten.

Zuweisungsvorlage für Antworten:

```
$util.toJson($ctx.result.data)
```

GraphQL-Antwort:

```
{
  "data": {
    "getReadings": [
      {
        "sensorId": "1",
        "timestamp": "2018-02-01T17:21:05.000+08:00",
        "lat": 47.615063,
        "long": -122.333551
      },
      {
        "sensorId": "1",
        "timestamp": "2018-02-01T17:21:05.000+08:00",
        "value": 85.5
      }
    ]
  }
}
```

Der Fehlerantwort werden keine Fehler hinzugefügt, da nur auf Daten reagiert wird.

#### 2. Melden eines Fehlers, um die Vorlagenausführung abzubrechen
<a name="raising-an-error-to-abort-the-template-execution"></a>

Wenn Teilausfälle aus der Perspektive des Clients als vollständige Ausfälle behandelt werden sollten, können Sie die Ausführung der Vorlage abbrechen, um die Rückgabe von Daten zu verhindern. Das Dienstprogramm `$util.error(...)` erzielt genau dieses Verhalten.

Zuweisungsvorlage für Antworten:

```
## there was an error let's mark the entire field
## as failed and do not return any data back in the response
#if ($ctx.error)
    $util.error($ctx.error.message, $ctx.error.type, null, $ctx.result.data.unprocessedKeys)
#end

$util.toJson($ctx.result.data)
```

GraphQL-Antwort:

```
{
  "data": {
    "getReadings": null
  },
  "errors": [
    {
      "path": [
        "getReadings"
      ],
      "data": null,
      "errorType": "DynamoDB:ProvisionedThroughputExceededException",
      "errorInfo": {
        "temperatureReadings": [
          {
            "sensorId": "1",
            "timestamp": "2018-02-01T17:21:05.000+08:00"
          }
        ],
        "locationReadings": []
      },
      "locations": [
        {
          "line": 58,
          "column": 3
        }
      ],
      "message": "You exceeded your maximum allowed provisioned throughput for a table or for one or more global secondary indexes. (...)"
    }
  ]
}
```

Auch wenn der DynamoDB Stapelvorgang möglicherweise einige Ergebnisse zurückgegeben hat, haben wir uns entschieden, einen Fehler zu melden, indem das GraphQL-Feld `getReadings` mit Null angezeigt und der Fehler dem *Fehler*-Block der GraphQL-Antwort hinzugefügt wurde.

#### 3. Anfügen eines Fehlers bei der Rückgabe von Daten und Fehlern
<a name="appending-an-error-to-return-both-data-and-errors"></a>

In bestimmten Fällen können Anwendungen Teilergebnisse zurückgeben und die Clients über die unverarbeiteten Elemente benachrichtigen und so die Benutzererfahrung verbessern. Die Clients können entscheiden, eine Wiederholung zu implementieren oder den Fehler an den Endbenutzer zu übermitteln. Über das Dienstprogramm `$util.appendError(...)` kann der Anwendungs-Designer Fehler im Hinblick auf den Kontext anfügen, ohne dass sich dies auf die Bewertung der Vorlage auswirkt. Nach der Auswertung der Vorlage AWS AppSync werden alle Kontextfehler verarbeitet, indem sie an den Fehlerblock der GraphQL-Antwort angehängt werden.

Zuweisungsvorlage für Antworten:

```
#if ($ctx.error)
    ## pass the unprocessed keys back to the caller via the `errorInfo` field
    $util.appendError($ctx.error.message, $ctx.error.type, null, $ctx.result.data.unprocessedKeys)
#end

$util.toJson($ctx.result.data)
```

Wir haben sowohl den Aufruffehler als auch das unprocessedKeys-Element an den Fehlerblock der GraphQL-Antwort weitergeleitet. Das `getReadings`-Feld gibt auch partielle Daten aus der **locationReadings**-Tabelle zurück, wie Sie in der nachstehenden Antwort sehen können.

GraphQL-Antwort:

```
{
  "data": {
    "getReadings": [
      null,
      {
        "sensorId": "1",
        "timestamp": "2018-02-01T17:21:05.000+08:00",
        "value": 85.5
      }
    ]
  },
  "errors": [
    {
      "path": [
        "getReadings"
      ],
      "data": null,
      "errorType": "DynamoDB:ProvisionedThroughputExceededException",
      "errorInfo": {
        "temperatureReadings": [
          {
            "sensorId": "1",
            "timestamp": "2018-02-01T17:21:05.000+08:00"
          }
        ],
        "locationReadings": []
      },
      "locations": [
        {
          "line": 58,
          "column": 3
        }
      ],
      "message": "You exceeded your maximum allowed provisioned throughput for a table or for one or more global secondary indexes. (...)"
    }
  ]
}
```