Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.
Utilisation des opérations par lots DynamoDB dans AWS AppSync
AWS AppSync prend en charge l'utilisation des opérations par lots Amazon DynamoDB sur une ou plusieurs tables d'une même région. Les opérations prises en charge sont BatchGetItem
, BatchPutItem
et BatchDeleteItem
. En utilisant ces fonctionnalités dans AWS AppSync, vous pouvez effectuer des tâches telles que :
-
Transmission d'une liste de clés en une seule requête et renvoi des résultats à partir d'une table
-
Lecture d'enregistrements d'une ou de plusieurs tables en une seule requête
-
Écrire des enregistrements en bloc dans une ou plusieurs tables
-
Écrire ou supprimer de manière conditionnelle des enregistrements dans plusieurs tables susceptibles d'avoir une relation
Les opérations par lots AWS AppSync présentent deux différences principales par rapport aux opérations non groupées :
-
Le rôle de source de données doit disposer d'autorisations sur toutes les tables auxquelles le résolveur aura accès.
-
La spécification de table pour un résolveur fait partie de l'objet de demande.
Lots à table unique
Avertissement
BatchPutItem
et ne BatchDeleteItem
sont pas pris en charge lorsqu'ils sont utilisés avec la détection et la résolution de conflits. Ces paramètres doivent être désactivés pour éviter d'éventuelles erreurs.
Pour commencer, créons un nouveau GraphQLAPI. Dans la AWS AppSync console, choisissez Create APIAPIs, GraphQL et Design from scratch. Nommez votre nom APIBatchTutorial API
, choisissez Next, puis à l'étape Spécifier les ressources GraphQL, choisissez Create GraphQL resources later et cliquez sur Next. Vérifiez vos informations et créez leAPI. Accédez à la page Schéma et collez le schéma suivant, en notant que pour la requête, nous allons transmettre une liste de 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] }
Enregistrez votre schéma et choisissez Create Resources en haut de la page. Choisissez Utiliser le type existant, puis sélectionnez le Post
type. Donnez un nom à votre tablePosts
. Assurez-vous que la clé primaire est définie surid
, désélectionnez Générer automatiquement GraphQL (vous fournirez votre propre code), puis sélectionnez Créer. Pour commencer, AWS AppSync
crée une nouvelle table DynamoDB et une source de données connectée à la table avec les rôles appropriés. Cependant, vous devez encore ajouter quelques autorisations au rôle. Accédez à la page Sources de données et choisissez la nouvelle source de données. Sous Sélectionnez un rôle existant, vous remarquerez qu'un rôle a été automatiquement créé pour le tableau. Prenez note du rôle (cela devrait ressembler à quelque chose comme çaappsync-ds-ddb-aaabbbcccddd-Posts
), puis accédez à la IAM console (https://console.aws.amazon.com/iam/+
« » à côté de la politique (le nom doit être similaire au nom du rôle). Choisissez Modifier en haut du pliable lorsque la politique apparaît. Vous devez ajouter des autorisations par lots à votre politique, en particulier dynamodb:BatchGetItem
etdynamodb:BatchWriteItem
. Cela ressemblera à ceci :
{ "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:…" ] } ] }
Choisissez Suivant, puis Enregistrer les modifications. Votre politique devrait autoriser le traitement par lots dès maintenant.
De retour dans la AWS AppSync console, accédez à la page Schéma et sélectionnez Joindre à côté du Mutation.batchAdd
champ. Créez votre résolveur en utilisant le Posts
tableau comme source de données. Dans l'éditeur de code, remplacez les gestionnaires par l'extrait ci-dessous. Cet extrait prend automatiquement chaque élément du input PostInput
type GraphQL et crée une carte, nécessaire à l'opération : 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; }
Accédez à la page Requêtes de la AWS AppSync console et exécutez la batchAdd
mutation suivante :
mutation add { batchAdd(posts:[{ id: 1 title: "Running in the Park"},{ id: 2 title: "Playing fetch" }]){ id title } }
Vous devriez voir les résultats imprimés à l'écran ; cela peut être validé en consultant la console DynamoDB pour rechercher les valeurs écrites dans la table. Posts
Répétez ensuite le processus consistant à joindre un résolveur, sauf pour le Query.batchGet
champ utilisant la Posts
table comme source de données. Remplacez les gestionnaires par le code ci-dessous. Ce processus prend automatiquement chaque élément du type GraphQL ids:[]
et crée une mappe, qui est nécessaire pour l'opération BatchGetItem
:
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; }
Retournez maintenant à la page Requêtes de la AWS AppSync console et exécutez la batchGet
requête suivante :
query get { batchGet(ids:[1,2,3]){ id title } }
Vous devez obtenir les résultats des deux valeurs id
que vous avez ajoutées précédemment. Notez qu'une null
valeur a été renvoyée pour le id
avec une valeur de3
. Cela est dû au fait qu'il n'y avait pas encore d'enregistrement dans votre Posts
table contenant cette valeur. Notez également que cela AWS AppSync renvoie les résultats dans le même ordre que les clés transmises à la requête, ce qui constitue une fonctionnalité supplémentaire qui AWS AppSync fonctionne en votre nom. Donc, si vous passez àbatchGet(ids:[1,3,2])
, vous verrez que la commande a changé. Vous saurez également quel id
a renvoyé une valeur null
.
Enfin, attachez un autre résolveur au Mutation.batchDelete
champ en utilisant la Posts
table comme source de données. Remplacez les gestionnaires par le code ci-dessous. Ce processus prend automatiquement chaque élément du type GraphQL ids:[]
et crée une mappe, qui est nécessaire pour l'opération BatchGetItem
:
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; }
Retournez maintenant à la page Requêtes de la AWS AppSync console et exécutez la batchDelete
mutation suivante :
mutation delete { batchDelete(ids:[1,2]){ id } }
Les enregistrements contenant les id
1
et 2
doivent désormais avoir été supprimés. Si vous exécutez à nouveau la requête batchGet()
à partir de l'état précédent, le résultat renvoyé devrait être null
.
Lot multi-tables
Avertissement
BatchPutItem
et ne BatchDeleteItem
sont pas pris en charge lorsqu'ils sont utilisés avec la détection et la résolution de conflits. Ces paramètres doivent être désactivés pour éviter d'éventuelles erreurs.
AWS AppSync vous permet également d'effectuer des opérations par lots sur plusieurs tables. Créons un application plus complexe. Imaginez que nous sommes en train de créer une application de santé pour animaux de compagnie dans laquelle des capteurs signalent l'emplacement et la température corporelle de l'animal. Les capteurs sont alimentés par piles et tentent de se connecter au réseau toutes les deux ou trois minutes. Lorsqu'un capteur établit une connexion, il envoie ses relevés à notre AWS AppSync API. Des déclencheurs analysent alors les données afin de pouvoir transmettre un tableau de bord au propriétaire de l'animal. Concentrons-nous sur la représentation des interactions entre le capteur et le magasin de données backend.
Dans la AWS AppSync console, choisissez Create APIAPIs, GraphQL et Design from scratch. Nommez votre nom APIMultiBatchTutorial API
, choisissez Next, puis à l'étape Spécifier les ressources GraphQL, choisissez Create GraphQL resources later et cliquez sur Next. Vérifiez vos informations et créez leAPI. Accédez à la page Schéma, collez et enregistrez le schéma suivant :
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 }
Nous devons créer deux tables DynamoDB :
-
locationReadings
enregistrera les relevés de position du capteur. -
temperatureReadings
enregistrera les relevés de température du capteur.
Les deux tables partageront la même structure de clé primaire : sensorId (String)
en tant que clé de partition et timestamp (String)
en tant que clé de tri.
Choisissez Créer des ressources en haut de la page. Choisissez Utiliser le type existant, puis sélectionnez le locationReadings
type. Donnez un nom à votre tablelocationReadings
. Assurez-vous que la clé primaire est définie sur sensorId
et que la clé de tri est définie surtimestamp
. Désélectionnez Générer automatiquement GraphQL (vous fournirez votre propre code), puis sélectionnez Créer. Répétez ce processus pour temperatureReadings
utiliser le temperatureReadings
comme type et nom de table. Utilisez les mêmes touches que ci-dessus.
Vos nouvelles tables contiendront les rôles générés automatiquement. Vous devez encore ajouter quelques autorisations à ces rôles. Accédez à la page Sources de données et choisissezlocationReadings
. Sous Sélectionner un rôle existant, vous pouvez voir le rôle. Prenez note du rôle (cela devrait ressembler à quelque chose comme çaappsync-ds-ddb-aaabbbcccddd-locationReadings
), puis accédez à la IAM console (https://console.aws.amazon.com/iam/+
« » à côté de la politique (le nom doit être similaire au nom du rôle). Choisissez Modifier en haut du pliable lorsque la politique apparaît. Vous devez ajouter des autorisations à cette politique. Cela ressemblera à ceci :
{ "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/*" ] } ] }
Choisissez Suivant, puis Enregistrer les modifications. Répétez ce processus pour la source de temperatureReadings
données en utilisant le même extrait de politique ci-dessus.
BatchPutItem - Enregistrement des lectures des capteurs
Nos capteurs doivent être en mesure d'envoyer leurs relevés une fois qu'ils sont connectés à Internet. Le champ GraphQL Mutation.recordReadings
est celui API qu'ils utiliseront pour ce faire. Nous devrons ajouter un résolveur à ce champ.
Sur la page Schéma de la AWS AppSync console, sélectionnez Joindre à côté du Mutation.recordReadings
champ. Sur l'écran suivant, créez votre résolveur en utilisant le locationReadings
tableau comme source de données.
Après avoir créé votre résolveur, remplacez les gestionnaires par le code suivant dans l'éditeur. Cette BatchPutItem
opération nous permet de spécifier plusieurs tables :
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 }
Les opérations par lots peuvent renvoyer à la fois des erreurs et des résultats à la suite de l'appel. Dans ce cas, nous pouvons effectuer certaines opérations de traitement des erreurs supplémentaires.
Note
L'utilisation de utils.appendError()
est similaire à lautil.error()
, avec la principale différence qu'elle n'interrompt pas l'évaluation du gestionnaire de demandes ou de réponses. Il signale plutôt qu'une erreur s'est produite dans le champ, mais permet d'évaluer le gestionnaire et, par conséquent, de renvoyer les données à l'appelant. Nous vous recommandons de l'utiliser utils.appendError()
lorsque votre application doit renvoyer des résultats partiels.
Enregistrez le résolveur et accédez à la page Requêtes de la AWS AppSync console. Nous pouvons maintenant envoyer des relevés de capteurs.
Exécutez la mutation suivante :
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 } } }
Nous avons envoyé dix relevés de capteurs pour une mutation, répartis sur deux tableaux. Utilisez la console DynamoDB pour vérifier que les données apparaissent à la fois dans les locationReadings
tables et. temperatureReadings
BatchDeleteItem - Suppression des relevés du capteur
De même, nous devrions également être en mesure de supprimer des lots de relevés de capteurs. Nous allons utiliser le champ GraphQL Mutation.deleteReadings
à cet effet. Sur la page Schéma de la AWS AppSync console, sélectionnez Joindre à côté du Mutation.deleteReadings
champ. Sur l'écran suivant, créez votre résolveur en utilisant le locationReadings
tableau comme source de données.
Après avoir créé votre résolveur, remplacez les gestionnaires de l'éditeur de code par l'extrait ci-dessous. Dans ce résolveur, nous utilisons un mappeur de fonctions auxiliaires qui extrait le sensorId
et timestamp
à partir des entrées fournies.
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 }
Enregistrez le résolveur et accédez à la page Requêtes de la AWS AppSync console. Supprimons maintenant quelques mesures du capteur.
Exécutez la mutation suivante :
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 } } }
Note
Contrairement à l'opération DeleteItem
, l'élément complètement supprimé n'est pas renvoyé dans la réponse. Seule la clé passée est renvoyée. Pour en savoir plus, consultez la référence de la fonction BatchDeleteItem in JavaScript resolver pour DynamoDB.
Vérifiez via la console DynamoDB que ces deux lectures ont été supprimées locationReadings
des tables et. temperatureReadings
BatchGetItem - Récupérez les lectures
Une autre opération courante de notre application consiste à récupérer les mesures d'un capteur à un moment précis. Nous allons joindre un résolveur au champ GraphQL Query.getReadings
dans notre schéma. Sur la page Schéma de la AWS AppSync console, sélectionnez Joindre à côté du Query.getReadings
champ. Sur l'écran suivant, créez votre résolveur en utilisant le locationReadings
tableau comme source de données.
Utilisons le code suivant :
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' })), ] }
Enregistrez le résolveur et accédez à la page Requêtes de la AWS AppSync console. Maintenant, récupérons les relevés de nos capteurs.
Exécutez la requête suivante :
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 } } }
Nous avons démontré avec succès l'utilisation des opérations par lots DynamoDB en utilisant. AWS AppSync
Gestion des erreurs
Dans AWS AppSync, les opérations de source de données peuvent parfois renvoyer des résultats partiels. Le terme résultats partiels est le terme que nous allons utiliser pour désigner une sortie d'opération composée de données et d'une erreur. La gestion des erreurs étant intrinsèquement spécifique à l'application, AWS AppSync vous avez la possibilité de gérer les erreurs dans le gestionnaire de réponses. L'erreur d'appel du résolveur, le cas échéant, est disponible depuis le contexte sous la forme ctx.error
. Les erreurs d'appel incluent toujours un message et un type, accessibles sous la forme des propriétés ctx.error.message
et ctx.error.type
. Dans le gestionnaire de réponses, vous pouvez gérer les résultats partiels de trois manières :
-
Avalez l'erreur d'invocation en renvoyant simplement des données.
-
Déclenchez une erreur (utilisation
util.error(...)
) en arrêtant l'évaluation du gestionnaire, qui ne renverra aucune donnée. -
Ajoutez une erreur (en utilisant
util.appendError(...)
) et renvoyez également des données.
Démontrons chacun des trois points ci-dessus avec les opérations par lots DynamoDB.
Opérations par lots DynamoDB
Dans le cas des opérations par lots DynamoDB, il est possible qu'un lot ne soit exécuté que partiellement. En d'autres termes, il est possible que certains des éléments ou des clés demandés ne soient pas traités. S'il n' AWS AppSync est pas possible de terminer un lot, les éléments non traités et une erreur d'invocation seront définis dans le contexte.
Nous allons mettre en œuvre la gestion des erreurs à l'aide de la configuration de champ Query.getReadings
de l'opération BatchGetItem
provenant de la section précédente de ce didacticiel. Cette fois, nous allons supposer que, lors de l'exécution du champ Query.getReadings
, la table DynamoDB temperatureReadings
a dépassé le débit alloué. DynamoDB a déclenché ProvisionedThroughputExceededException
un lors de la deuxième tentative pour traiter AWS AppSync les éléments restants du lot.
Ce qui suit JSON représente le contexte sérialisé après l'appel par lots DynamoDB mais avant l'appel du gestionnaire de réponses :
{ "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": [] }
Quelques points à noter concernant le contexte :
-
L'erreur d'invocation a été définie sur le contexte et AWS AppSync le type d'erreur a été défini sur.
ctx.error
DynamoDB:ProvisionedThroughputExceededException
-
Les résultats sont mappés par table ci-dessous
ctx.result.data
même en cas d'erreur. -
Les clés qui n'ont pas été traitées sont disponibles sur
ctx.result.data.unprocessedKeys
. Ici, AWS AppSync impossible de récupérer l'élément avec la clé (:1sensorId, Timestamp:2018-02-01T 17:21:05.000 + 08:00) en raison d'un débit de table insuffisant.
Note
Pour BatchPutItem
, la valeur est ctx.result.data.unprocessedItems
. Pour BatchDeleteItem
, la valeur est ctx.result.data.unprocessedKeys
.
Nous allons traiter cette erreur de trois façons différentes.
1. Digestion de l'erreur d'appel
Le renvoi des données sans gestion de l'erreur d'appel se traduit par une digestion de l'erreur, ce qui permet au résultat du champ GraphQL donné d'être toujours réussi.
Le code que nous écrivons est familier et se concentre uniquement sur les données de résultat.
Gestionnaire de réponses
export function response(ctx) { return ctx.result.data }
Réponse GraphQL
{ "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 } ] } }
Aucune erreur n'est ajoutée à la réponse d'erreur car l'action n'a porté que sur les données.
2. Génération d'une erreur pour annuler l'exécution du gestionnaire de réponses
Lorsque les échecs partiels doivent être traités comme des échecs complets du point de vue du client, vous pouvez interrompre l'exécution du gestionnaire de réponses pour empêcher le renvoi de données. La méthode d'utilitaire util.error(...)
permet d'obtenir exactement ce comportement.
Code du gestionnaire de réponses
export function response(ctx) { if (ctx.error) { util.error(ctx.error.message, ctx.error.type, null, ctx.result.data.unprocessedKeys); } return ctx.result.data; }
Réponse GraphQL
{ "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. (...)" } ] }
Même si certains résultats peuvent avoir été renvoyés par l'opération de traitement par lots DynamoDB, nous avons choisi de déclencher une erreur se traduisant par une valeur null pour le champ GraphQL getReadings
et l'erreur a été ajoutée au bloc d'erreurs de la réponse GraphQL.
3. Ajout d'une erreur pour renvoyer à la fois les données et les erreurs
Dans certains cas, afin d'offrir une meilleure expérience utilisateur, les applications peuvent renvoyer des résultats partiels et informer leurs clients des éléments non traités. Les clients peuvent choisir d'implémenter une nouvelle tentative ou de renvoyer l'erreur à l'utilisateur final. util.appendError(...)
Il s'agit de la méthode utilitaire qui permet ce comportement en permettant au concepteur de l'application d'ajouter des erreurs au contexte sans interférer avec l'évaluation du gestionnaire de réponses. Après avoir évalué le gestionnaire de réponse, AWS AppSync traitera toutes les erreurs de contexte en les ajoutant au bloc d'erreurs de la réponse GraphQL.
Code du gestionnaire de réponses
export function response(ctx) { if (ctx.error) { util.appendError(ctx.error.message, ctx.error.type, null, ctx.result.data.unprocessedKeys); } return ctx.result.data; }
Nous avons transmis à la fois l'erreur d'invocation et l'unprocessedKeys
élément contenu dans le bloc d'erreurs de la réponse GraphQL. Le getReadings
champ renvoie également des données partielles de la locationReadings
table, comme vous pouvez le voir dans la réponse ci-dessous.
Réponse GraphQL
{ "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. (...)" } ] }