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
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
-
Übergeben einer Schlüsselliste in einer einzigen Abfrage und Rückgabe der Ergebnisse aus einer Tabelle
-
Lesen von Datensätzen aus einer oder mehreren Tabellen in einer einzigen Abfrage
-
Speichern von Datensätzen in großen Mengen in eine oder mehrere Tabellen
-
Bedingtes Schreiben oder Löschen von Datensätzen in mehreren Tabellen, die möglicherweise eine Beziehung haben
Batch-Operationen AWS AppSync weisen zwei wesentliche Unterschiede zu Vorgängen ohne Batch auf:
-
Die Datenquellenrolle muss über Berechtigungen für alle Tabellen verfügen, auf die der Resolver zugreift.
-
Die Tabellenspezifikation für einen Resolver ist Teil des Anforderungsobjekts.
Batches aus einzelnen Tabellen
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.
Lassen Sie uns zunächst ein neues GraphQL API erstellen. Wählen Sie in der AWS AppSync Konsole Create API, GraphQL APIs und Design from scratch aus. Geben Sie Ihren Namen APIBatchTutorial API
, wählen Sie Weiter und wählen Sie im Schritt GraphQL-Ressourcen angeben die Option GraphQL-Ressourcen später erstellen aus und klicken Sie auf Weiter. Überprüfen Sie Ihre Daten und erstellen Sie die. API Gehen Sie zur Schema-Seite und fügen Sie das folgende Schema ein. Beachten Sie dabei, 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] }
Speichern Sie Ihr Schema und wählen Sie oben auf der Seite Ressourcen erstellen aus. Wählen Sie Bestehenden Typ verwenden und wählen Sie den Post
Typ aus. Benennen Sie Ihre TabellePosts
. Stellen Sie sicher, dass der Primärschlüssel auf eingestellt istid
, deaktivieren Sie die Option GraphQL automatisch generieren (Sie geben Ihren eigenen Code an) und wählen Sie Erstellen aus. AWS AppSync
Erstellt zunächst eine neue DynamoDB-Tabelle und eine mit der Tabelle verbundene Datenquelle mit den entsprechenden Rollen. Es gibt jedoch noch einige Berechtigungen, die Sie der Rolle hinzufügen müssen. Gehen Sie zur Seite Datenquellen und wählen Sie die neue Datenquelle aus. Unter Wählen Sie eine vorhandene Rolle aus werden Sie feststellen, dass automatisch eine Rolle für die Tabelle erstellt wurde. Notieren Sie sich die Rolle (sollte ungefähr so aussehenappsync-ds-ddb-aaabbbcccddd-Posts
) und gehen Sie dann zur IAM Konsole (https://console.aws.amazon.com/iam/+
" neben der Richtlinie (sollte einen ähnlichen Namen wie der Rollenname haben). Wenn die Richtlinie angezeigt wird, wählen Sie oben in der zusammenklappbaren Ansicht die Option Bearbeiten aus. Sie müssen Ihrer Richtlinie Batch-Berechtigungen hinzufügen, insbesondere dynamodb:BatchGetItem
unddynamodb:BatchWriteItem
. Es wird ungefähr so aussehen:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "dynamodb:DeleteItem", "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:Query", "dynamodb:Scan", "dynamodb:UpdateItem", "dynamodb:BatchWriteItem", "dynamodb:BatchGetItem" ], "Resource": [ "arn:aws:dynamodb:…", "arn:aws:dynamodb:…" ] } ] }
Wählen Sie Weiter und dann Änderungen speichern. Ihre Richtlinie sollte jetzt die Stapelverarbeitung zulassen.
Gehen Sie zurück in der AWS AppSync Konsole zur Schemaseite und wählen Sie neben dem Mutation.batchAdd
Feld die Option Anhängen aus. Erstellen Sie Ihren Resolver mit der Posts
Tabelle als Datenquelle. Ersetzen Sie im Code-Editor die Handler durch das folgende Snippet. Dieses Snippet nimmt automatisch jedes Element input PostInput
vom Typ GraphQL und erstellt eine Map, die für den Vorgang benötigt wird: BatchPutItem
import { util } from "@aws-appsync/utils"; export function request(ctx) { return { operation: "BatchPutItem", tables: { Posts: ctx.args.posts.map((post) => util.dynamodb.toMapValues(post)), }, }; } export function response(ctx) { if (ctx.error) { util.error(ctx.error.message, ctx.error.type); } return ctx.result.data.Posts; }
Navigieren Sie zur Seite „Abfragen“ der AWS AppSync Konsole und führen Sie die folgende Mutation aus: batchAdd
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. Sie können dies überprüfen, indem Sie die DynamoDB-Konsole überprüfen, um nach den in die Tabelle geschriebenen Werten zu suchen. Posts
Als Nächstes wiederholen Sie den Vorgang des Anfügens eines Resolvers, jedoch für das Query.batchGet
Feld, wobei die Posts
Tabelle als Datenquelle verwendet wird. Ersetzen Sie die Handler durch den folgenden Code. Hierdurch wird automatisch jedes Element im GraphQL ids:[]
-Typ berücksichtigt und eine Zuordnung erstellt, wie sie für die BatchGetItem
-Operation erforderlich ist:
import { util } from "@aws-appsync/utils"; export function request(ctx) { return { operation: "BatchGetItem", tables: { Posts: { keys: ctx.args.ids.map((id) => util.dynamodb.toMapValues({ id })), consistentRead: true, }, }, }; } export function response(ctx) { if (ctx.error) { util.error(ctx.error.message, ctx.error.type); } return ctx.result.data.Posts; }
Gehen Sie jetzt zurück zur Abfrageseite 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 für den ein null
Wert id
mit dem Wert von zurückgegeben wurde3
. Das liegt daran, dass es in Ihrer Posts
Tabelle noch keinen Datensatz mit diesem Wert gab. Beachten Sie außerdem, 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 AWS AppSync in Ihrem Namen ausgeführt wird. Wenn Sie also zu wechselnbatchGet(ids:[1,3,2])
, werden Sie feststellen, 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 abschließend einen weiteren Resolver an das Mutation.batchDelete
Feld an, indem Sie die Posts
Tabelle als Datenquelle verwenden. Ersetzen Sie die Handler durch den folgenden Code. Hierdurch wird automatisch jedes Element im GraphQL ids:[]
-Typ berücksichtigt und eine Zuordnung erstellt, wie sie für die BatchGetItem
-Operation erforderlich ist:
import { util } from "@aws-appsync/utils"; export function request(ctx) { return { operation: "BatchDeleteItem", tables: { Posts: ctx.args.ids.map((id) => util.dynamodb.toMapValues({ id })), }, }; } export function response(ctx) { if (ctx.error) { util.error(ctx.error.message, ctx.error.type); } return ctx.result.data.Posts; }
Gehen Sie jetzt zurück zur Abfrageseite 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.
Batch mit mehreren Tabellen
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 App zur Tiergesundheit, bei der Sensoren den Standort und die Körpertemperatur des Tieres melden. 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.
Wählen Sie in der AWS AppSync Konsole Create API, GraphQL APIs und Design from scratch aus. Geben Sie Ihren Namen APIMultiBatchTutorial API
, wählen Sie Weiter und wählen Sie im Schritt GraphQL-Ressourcen angeben die Option GraphQL-Ressourcen später erstellen aus und klicken Sie auf Weiter. Überprüfen Sie Ihre Daten und erstellen Sie die. API Gehen Sie zur Schemaseite und fügen Sie das folgende Schema ein und speichern Sie es:
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 }
Wir müssen zwei DynamoDB-Tabellen erstellen:
-
locationReadings
speichert die Messwerte der Sensorposition. -
temperatureReadings
speichert die Sensortemperaturwerte.
Beide Tabellen werden dieselbe Primärschlüsselstruktur haben: sensorId (String)
als Partitionsschlüssel und timestamp (String)
als Sortierschlüssel.
Wählen Sie oben auf der Seite Create Resources aus. Wählen Sie Bestehenden Typ verwenden und wählen Sie den locationReadings
Typ aus. Benennen Sie Ihre TabellelocationReadings
. Stellen Sie sicher, dass der Primärschlüssel auf sensorId
und der Sortierschlüssel auf eingestellt sindtimestamp
. Deaktivieren Sie die Option GraphQL automatisch generieren (Sie stellen Ihren eigenen Code bereit) und wählen Sie Erstellen aus. Wiederholen Sie diesen Vorgang, um den temperatureReadings
als Typ und Tabellennamen zu temperatureReadings
verwenden. Verwenden Sie dieselben Tasten wie oben.
Ihre neuen Tabellen werden automatisch generierte Rollen enthalten. Es gibt noch einige Berechtigungen, die Sie diesen Rollen hinzufügen müssen. Gehen Sie zur Seite Datenquellen und wählen SielocationReadings
. Unter Wählen Sie eine bestehende Rolle aus können Sie die Rolle sehen. Notieren Sie sich die Rolle (sollte ungefähr so aussehenappsync-ds-ddb-aaabbbcccddd-locationReadings
) und gehen Sie dann zur IAM Konsole (https://console.aws.amazon.com/iam/+
" neben der Richtlinie (sollte einen ähnlichen Namen wie der Rollenname haben). Wenn die Richtlinie angezeigt wird, wählen Sie oben in der zusammenklappbaren Ansicht die Option Bearbeiten aus. Sie müssen dieser Richtlinie Berechtigungen hinzufügen. Es wird ungefähr so aussehen:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "dynamodb:DeleteItem", "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:Query", "dynamodb:Scan", "dynamodb:UpdateItem", "dynamodb:BatchGetItem", "dynamodb:BatchWriteItem" ], "Resource": [ "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/*" ] } ] }
Wählen Sie Weiter und dann Änderungen speichern. Wiederholen Sie diesen Vorgang für die temperatureReadings
Datenquelle mit demselben Richtlinienausschnitt oben.
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. Wir müssen diesem Feld einen Resolver hinzufügen.
Wählen Sie auf der Schemaseite der AWS AppSync Konsole neben dem Mutation.recordReadings
Feld die Option Anhängen aus. Erstellen Sie auf dem nächsten Bildschirm Ihren Resolver mit der locationReadings
Tabelle als Datenquelle.
Nachdem Sie Ihren Resolver erstellt haben, ersetzen Sie die Handler im Editor durch den folgenden Code. Diese BatchPutItem
Operation ermöglicht es uns, mehrere Tabellen anzugeben:
import { util } from '@aws-appsync/utils' export function request(ctx) { const { locReadings, tempReadings } = ctx.args const locationReadings = locReadings.map((loc) => util.dynamodb.toMapValues(loc)) const temperatureReadings = tempReadings.map((tmp) => util.dynamodb.toMapValues(tmp)) return { operation: 'BatchPutItem', tables: { locationReadings, temperatureReadings, }, } } export function response(ctx) { if (ctx.error) { util.appendError(ctx.error.message, ctx.error.type) } return 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.
Anmerkung
Die Verwendung von utils.appendError()
ähnelt derutil.error()
, mit dem wesentlichen Unterschied, dass sie die Auswertung des Anfrage- oder Antworthandlers nicht unterbricht. Stattdessen signalisiert es, dass ein Fehler mit dem Feld aufgetreten ist, ermöglicht aber die Auswertung des Handlers und damit die Rückgabe von Daten an den Aufrufer. Wir empfehlen die Verwendung, utils.appendError()
wenn Ihre Anwendung Teilergebnisse zurückgeben muss.
Speichern Sie den Resolver und navigieren Sie in der AWS AppSync Konsole zur Seite Abfragen. Wir können jetzt einige Sensorwerte senden.
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 haben zehn Sensorwerte in einer Mutation gesendet, wobei die Messwerte auf zwei Tabellen aufgeteilt wurden. Verwenden Sie die DynamoDB-Konsole, um zu überprüfen, ob die Daten sowohl in der als auch in der locationReadings
Tabelle angezeigt werden. temperatureReadings
BatchDeleteItem - Löschen von Sensormesswerten
In ähnlicher Weise müssten wir auch in der Lage sein, Chargen von Sensormesswerten zu löschen. Dazu verwenden wir das GraphQL-Feld Mutation.deleteReadings
. Wählen Sie auf der Schemaseite der AWS AppSync Konsole neben dem Mutation.deleteReadings
Feld die Option Anhängen aus. Erstellen Sie auf dem nächsten Bildschirm Ihren Resolver mit der locationReadings
Tabelle als Datenquelle.
Nachdem Sie Ihren Resolver erstellt haben, ersetzen Sie die Handler im Code-Editor durch das folgende Snippet. In diesem Resolver verwenden wir einen Hilfsfunktions-Mapper, der die sensorId
und aus den bereitgestellten Eingaben extrahiert. timestamp
import { util } from '@aws-appsync/utils' export function request(ctx) { const { locReadings, tempReadings } = ctx.args const mapper = ({ sensorId, timestamp }) => util.dynamodb.toMapValues({ sensorId, timestamp }) return { operation: 'BatchDeleteItem', tables: { locationReadings: locReadings.map(mapper), temperatureReadings: tempReadings.map(mapper), }, } } export function response(ctx) { if (ctx.error) { util.appendError(ctx.error.message, ctx.error.type) } return ctx.result.data }
Speichern Sie den Resolver und navigieren Sie zur Seite „Abfragen“ in der Konsole. AWS AppSync Lassen Sie uns nun ein paar 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 } } }
Anmerkung
Im Gegensatz zum DeleteItem
-Vorgang wird nicht das vollständig gelöschte Element in der Antwort zurückgegeben. Nur der übergebene Schlüssel wird zurückgegeben. Weitere Informationen finden Sie BatchDeleteItem in der JavaScript Resolver-Funktionsreferenz für DynamoDB.
Überprüfen Sie über die DynamoDB-Konsole, ob diese beiden Messwerte aus den Tabellen locationReadings
und temperatureReadings
gelöscht wurden.
BatchGetItem - Messwerte abrufen
Eine weitere übliche Operation für unsere App wäre das Abrufen der Messwerte für einen Sensor zu einem bestimmten Zeitpunkt. Fügen wir dazu einen Resolver zum GraphQL-Feld Query.getReadings
unseres Schemas hinzu. Wählen Sie auf der Schemaseite der AWS AppSync Konsole neben dem Query.getReadings
Feld die Option Anhängen aus. Erstellen Sie auf dem nächsten Bildschirm Ihren Resolver mit der locationReadings
Tabelle als Datenquelle.
Lassen Sie uns den folgenden Code verwenden:
import { util } from '@aws-appsync/utils' export function request(ctx) { const keys = [util.dynamodb.toMapValues(ctx.args)] const consistentRead = true return { operation: 'BatchGetItem', tables: { locationReadings: { keys, consistentRead }, temperatureReadings: { keys, consistentRead }, }, } } export function response(ctx) { if (ctx.error) { util.appendError(ctx.error.message, ctx.error.type) } const { locationReadings: locs, temperatureReadings: temps } = ctx.result.data return [ ...locs.map((l) => ({ ...l, __typename: 'LocationReading' })), ...temps.map((t) => ({ ...t, __typename: 'TemperatureReading' })), ] }
Speichern Sie den Resolver und navigieren Sie zur Seite „Abfragen“ in der AWS AppSync Konsole. Lassen Sie uns nun unsere Sensorwerte abrufen.
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 im Antworthandler 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.type
zugegriffen werden kann. Im Antworthandler können Sie Teilergebnisse auf drei Arten verarbeiten:
-
Überwinden Sie den Aufruffehler, indem Sie einfach Daten zurückgeben.
-
Einen Fehler (using
util.error(...)
) auslösen, indem Sie die Auswertung des Handlers beenden, wodurch keine Daten zurückgegeben werden. -
Fügt einen Fehler an (using
util.appendError(...)
) und gibt auch Daten zurück.
Lassen Sie uns jeden der drei oben genannten Punkte anhand von DynamoDB-Batchoperationen demonstrieren.
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 Batch 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.
Im Folgenden wird der JSON serialisierte Kontext nach dem DynamoDB-Batchaufruf, aber bevor der Antworthandler aufgerufen 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 gesetzt AWS AppSync, und der Fehlertyp wurde auf gesetzt.DynamoDB:ProvisionedThroughputExceededException
-
Die Ergebnisse werden pro Tabelle unter zugeordnet,
ctx.result.data
obwohl ein Fehler vorliegt. -
Schlüssel, die nicht verarbeitet wurden, sind unter verfügbar.
ctx.result.data.unprocessedKeys
Hier AWS AppSync konnte das Element mit dem Schlüssel (:1, timestamp:2018-02-01T sensorId 17:21:05.000 + 08:00) aufgrund des unzureichenden Tabellendurchsatzes nicht abgerufen werden.
Anmerkung
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.
Der Code, den wir schreiben, ist bekannt und konzentriert sich nur auf die Ergebnisdaten.
Antworthandler
export function response(ctx) { return 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. Es wird ein Fehler ausgelöst, um die Ausführung des Response-Handlers abzubrechen
Wenn Teilausfälle aus Sicht des Clients als vollständige Fehler behandelt werden sollen, können Sie die Ausführung des Antworthandlers abbrechen, um zu verhindern, dass Daten zurückgegeben werden. Das Dienstprogramm util.error(...)
erzielt genau dieses Verhalten.
Code des Antworthandlers
export function response(ctx) { if (ctx.error) { util.error(ctx.error.message, ctx.error.type, null, ctx.result.data.unprocessedKeys); } return 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. Dies util.appendError(...)
ist die Utility-Methode, die dieses Verhalten ermöglicht, indem sie es dem Anwendungsdesigner ermöglicht, Fehler an den Kontext anzuhängen, ohne die Auswertung des Antworthandlers zu beeinträchtigen. Nach der Auswertung des Antworthandlers AWS AppSync verarbeitet er alle Kontextfehler, indem er sie an den Fehlerblock der GraphQL-Antwort anhängt.
Code für den Antworthandler
export function response(ctx) { if (ctx.error) { util.appendError(ctx.error.message, ctx.error.type, null, ctx.result.data.unprocessedKeys); } return 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 locationReadings
Tabelle 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. (...)" } ] }