Tutorial: Verwenden von DynamoDB-Batchoperationen in AWS AppSync - AWS AppSync

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.

Tutorial: Verwenden von DynamoDB-Batchoperationen in AWS AppSync

Anmerkung

Wir unterstützen jetzt hauptsächlich die APPSYNC _JS-Laufzeit und ihre Dokumentation. Bitte erwägen Sie, die APPSYNC _JS-Laufzeit und ihre Anleitungen hier zu verwenden.

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. Mithilfe dieser Funktionen können Sie Aufgaben wie die folgenden ausführen: AWS AppSync

  • Ü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

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:

{ "Version": "2012-10-17", "Statement": [ { "Action": [ "dynamodb:BatchGetItem", "dynamodb:BatchWriteItem" ], "Effect": "Allow", "Resource": [ "arn:aws:dynamodb:region:account:table/TABLENAME", "arn:aws:dynamodb:region:account: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 würde in der obigen Richtlinie im Feld Ressource geschehen. IAM Die Konfiguration der Tabellen, um Stapelaufrufe auszuführen, erfolgt in der Resolver-Vorlage und wird nachfolgend beschrieben.

Datenquelle

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:

{ "Version": "2012-10-17", "Statement": [ { "Action": [ "dynamodb:BatchGetItem", "dynamodb:BatchWriteItem" ], "Effect": "Allow", "Resource": [ "arn:aws:dynamodb:region:account:table/Posts", "arn:aws:dynamodb:region:account:table/Posts/*", "arn:aws:dynamodb:region:account:table/locationReadings", "arn:aws:dynamodb:region:account:table/locationReadings/*", "arn:aws:dynamodb:region:account:table/temperatureReadings", "arn:aws:dynamodb:region:account:table/temperatureReadings/*" ] } ] }

Stapelvorgang mit einer Tabelle

Warnung

BatchPutItemund 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 übergebenIDs:

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 nun zur Seite „Abfragen“ der AWS AppSync Konsole und führen Sie die folgende batchAddMutation 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)

Gehen Sie nun zurück zur Seite „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 außerdem, dass die Ergebnisse in derselben Reihenfolge AWS AppSync zurückgegeben werden wie die an die Abfrage übergebenen Schlüssel. Dabei handelt es sich um eine zusätzliche Funktion, die AWS AppSync in Ihrem 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)

Gehen Sie nun zurück zur Abfrageseite der AWS AppSync Konsole und führen Sie die folgende batchDeleteMutation 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

Warnung

BatchPutItemund 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 unseren 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; locationReadingsspeichert die Sensorpositionswerte und temperatureReadingsspeichert die 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

Nachdem eine Verbindung zum Internet hergestellt wurde, müssen unsere Sensoren in der Lage sein, ihre Messwerte zu senden. Das GraphQL-Feld Mutation.recordReadings ist das FeldAPI, das sie dafür verwenden werden. Fügen wir einen Resolver hinzu, um unseren API zum Leben zu erwecken.

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 Seite „Abfragen“ 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 der als auch in der locationReadingsTabelle angezeigt werden. temperatureReadings

BatchDeleteItem - Löschen von Sensormesswerten

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!

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 locationReadingsund temperatureReadingsgelöscht wurden.

BatchGetItem - Messwerte abrufen

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 BatchGetItemOperation 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!

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

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 von Natur aus anwendungsspezifisch ist, AWS AppSync haben Sie die Möglichkeit, Fehler in der Antwortzuordnungsvorlage zu behandeln. 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.typezugegriffen 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

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

  3. 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

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 ProvisionedThroughputExceededExceptionbeim zweiten Versuch a ausgelöst, AWS AppSync um die verbleibenden Elemente im Stapel zu verarbeiten.

Im Folgenden wird der JSON serialisierte Kontext nach dem DynamoDB-Batchaufruf, aber bevor die Antwortzuordnungsvorlage ausgewertet wurde, dargestellt.

{ "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 (:1, timestamp:2018-02-01T 17:21:05.000 sensorId + 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

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

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

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 unprocessedKeys das Element innerhalb des Fehlerblocks der GraphQL-Antwort weitergeleitet. Das getReadings Feld gibt auch Teildaten aus der locationReadingsTabelle zurück, wie Sie in der folgenden 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. (...)" } ] }