Expressions de condition - AWS AppSync

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.

Expressions de condition

Lorsque vous mutez des objets dans DynamoDB à l'aide des opérationsPutItem,UpdateItem, et DeleteItem DynamoDB, vous pouvez éventuellement spécifier une expression de condition qui détermine si la demande doit aboutir ou non, en fonction de l'état de l'objet déjà présent dans DynamoDB avant l'exécution de l'opération.

Le résolveur AWS AppSync DynamoDB permet de spécifier une expression de condition PutItem dans DeleteItem et de demander des documents de mappageUpdateItem, ainsi qu'une stratégie à suivre si la condition échoue et que l'objet n'a pas été mis à jour.

Exemple 1

Le document de mappage PutItem suivant ne dispose pas d'une expression de condition. Par conséquent, il place un élément dans DynamoDB même s'il existe déjà un élément portant la même clé, remplaçant ainsi l'élément existant.

{ "version" : "2017-02-28", "operation" : "PutItem", "key" : { "id" : { "S" : "1" } } }

Exemple 2

Le document de PutItem mappage suivant contient une expression de condition qui permet à l'opération de réussir uniquement si un élément portant la même clé n'existe pas dans DynamoDB.

{ "version" : "2017-02-28", "operation" : "PutItem", "key" : { "id" : { "S" : "1" } }, "condition" : { "expression" : "attribute_not_exists(id)" } }

Par défaut, si le contrôle de condition échoue, le résolveur AWS AppSync DynamoDB renvoie une erreur concernant la mutation et la valeur actuelle de l'objet dans DynamoDB dans un data champ de la section de la réponse GraphQL. error Cependant, le résolveur AWS AppSync DynamoDB propose des fonctionnalités supplémentaires pour aider les développeurs à gérer certains cas extrêmes courants :

  • Si le résolveur AWS AppSync DynamoDB peut déterminer que la valeur actuelle dans DynamoDB correspond au résultat souhaité, il traite l'opération comme si elle avait réussi de toute façon.

  • Au lieu de renvoyer une erreur, vous pouvez configurer le résolveur pour appeler une fonction Lambda personnalisée afin de décider de la manière dont le résolveur AWS AppSync DynamoDB doit gérer la panne.

Cette opération est décrite plus en détail dans la section Gestion d'un échec de contrôle de condition.

Pour plus d'informations sur les expressions de conditions DynamoDB, consultez la documentation DynamoDB. ConditionExpressions

Spécifier une condition

Les documents de mappage des demandes PutItem, UpdateItem et DeleteItem permettent tous la spécification d'une section de condition facultative. Si cette section est omise, aucune vérification de condition n'est effectuée. Si elle est spécifiée, la condition doit être true pour que l'opération réussisse.

Une section condition a la structure suivante :

"condition" : { "expression" : "someExpression" "expressionNames" : { "#foo" : "foo" }, "expressionValues" : { ":bar" : ... typed value }, "equalsIgnore" : [ "version" ], "consistentRead" : true, "conditionalCheckFailedHandler" : { "strategy" : "Custom", "lambdaArn" : "arn:..." } }

Les champs suivants spécifient la condition :

expression

Expression de mise à jour elle-même. Pour plus d'informations sur la façon d'écrire des expressions de condition, consultez la documentation ConditionExpressions DynamoDB. Ce champ doit être spécifié.

expressionNames

Substituts des espaces réservés de nom des attributs de l'expression, sous la forme de paires clé-valeur. La clé correspond à un espace réservé utilisé dans l'expression, et la valeur doit être une chaîne correspondant au nom d'attribut de l'élément dans DynamoDB. Ce champ est facultatif et doit être renseigné uniquement avec des substituts des espaces réservés de nom des attributs de l'expression utilisés dans l'expression.

expressionValues

Substituts des espaces réservés de valeur des attributs de l'expression, sous la forme de paires clé-valeur. La clé correspond à un espace réservé de valeur utilisé dans l'expression, et la valeur doit être typée. Pour de plus amples informations sur la spécification d'une « valeur typée », veuillez consulter Système de types (mappage des requêtes). Cela doit être spécifié. Ce champ est facultatif et doit être renseigné uniquement avec des substituts des espaces réservés de valeur des attributs de l'expression utilisés dans l'expression.

Les champs restants indiquent au résolveur AWS AppSync DynamoDB comment gérer un échec de vérification de condition :

equalsIgnore

Lorsqu'une vérification de condition échoue lors de l'utilisation de l'PutItemopération, le résolveur AWS AppSync DynamoDB compare l'élément actuellement dans DynamoDB à l'élément qu'il a essayé d'écrire. S'ils sont identiques, il traite l'opération comme si elle avait réussi. Vous pouvez utiliser le equalsIgnore champ pour spécifier une liste d'attributs à AWS AppSync ignorer lors de cette comparaison. Par exemple, si la seule différence était un version attribut, il traite l'opération comme si elle avait réussi. Ce champ est facultatif.

consistentRead

Lorsqu'une vérification de condition échoue, AWS AppSync obtient la valeur actuelle de l'élément auprès de DynamoDB à l'aide d'une lecture hautement cohérente. Vous pouvez utiliser ce champ pour indiquer au résolveur AWS AppSync DynamoDB d'utiliser une lecture éventuellement cohérente à la place. Ce champ est facultatif et contient true par défaut.

conditionalCheckFailedHandler

Cette section vous permet de spécifier comment le résolveur AWS AppSync DynamoDB traite un échec de vérification de condition après avoir comparé la valeur actuelle dans DynamoDB au résultat attendu. Cette section est facultative. Si elle n'est pas spécifiée, la valeur par défaut est une stratégie Reject.

strategy

Stratégie adoptée par le résolveur AWS AppSync DynamoDB après avoir comparé la valeur actuelle dans DynamoDB au résultat attendu. Ce champ est obligatoire et les valeurs suivantes sont possibles :

Reject

La mutation échoue et une erreur se produit concernant la mutation et la valeur actuelle de l'objet dans DynamoDB dans data un champ de la section de error la réponse GraphQL.

Custom

Le résolveur AWS AppSync DynamoDB invoque une fonction Lambda personnalisée pour décider comment gérer l'échec du contrôle de condition. Lorsque le strategy est défini surCustom, le lambdaArn champ doit contenir ARN la fonction Lambda à invoquer.

lambdaArn

Fonction Lambda à invoquer qui détermine la manière dont le résolveur DynamoDB doit gérer l' AWS AppSync échec de la vérification des conditions. ARN Ce champ doit être spécifié uniquement lorsque strategy est défini sur Custom. Pour plus d'informations sur l'utilisation de cette fonction, consultez Gestion de l'échec d'une vérification de condition.

Gestion d'un échec de vérification d'état

Par défaut, lorsqu'une vérification de condition échoue, le résolveur AWS AppSync DynamoDB renvoie une erreur concernant la mutation et la valeur actuelle de l'objet dans DynamoDB dans un data champ de la section de la réponse GraphQL. error Cependant, le résolveur AWS AppSync DynamoDB propose des fonctionnalités supplémentaires pour aider les développeurs à gérer certains cas extrêmes courants :

  • Si le résolveur AWS AppSync DynamoDB peut déterminer que la valeur actuelle dans DynamoDB correspond au résultat souhaité, il traite l'opération comme si elle avait réussi de toute façon.

  • Au lieu de renvoyer une erreur, vous pouvez configurer le résolveur pour appeler une fonction Lambda personnalisée afin de décider de la manière dont le résolveur AWS AppSync DynamoDB doit gérer la panne.

Le diagramme de ce processus est le suivant :

Vérification du résultat souhaité

Lorsque le contrôle de condition échoue, le résolveur AWS AppSync DynamoDB exécute GetItem une requête DynamoDB pour obtenir la valeur actuelle de l'élément auprès de DynamoDB. Par défaut, il utilise une lecture à cohérence forte, mais cela peut être configuré à l'aide du champ consistentRead dans le bloc condition et comparé aux résultats prévus :

  • Pour l'PutItemopération, le résolveur AWS AppSync DynamoDB compare la valeur actuelle à celle qu'il a tenté d'écrire, en excluant les attributs répertoriés dans equalsIgnore la comparaison. Si les éléments sont identiques, il considère l'opération comme réussie et renvoie l'élément extrait de DynamoDB. Dans le cas contraire, il suit la stratégie configurée.

    Par exemple, si le document de mappage des requêtes PutItem ressemble à ce qui suit :

    { "version" : "2017-02-28", "operation" : "PutItem", "key" : { "id" : { "S" : "1" } }, "attributeValues" : { "name" : { "S" : "Steve" }, "version" : { "N" : 2 } }, "condition" : { "expression" : "version = :expectedVersion", "expressionValues" : { ":expectedVersion" : { "N" : 1 } }, "equalsIgnore": [ "version" ] } }

    Et si l'élément actuellement dans DynamoDB ressemble à ce qui suit :

    { "id" : { "S" : "1" }, "name" : { "S" : "Steve" }, "version" : { "N" : 8 } }

    Le résolveur AWS AppSync DynamoDB comparait l'élément qu'il a essayé d'écrire à la valeur actuelle, constatant que la seule différence réside dans version le champ, mais comme il est configuré pour ignorer version le champ, il considère l'opération comme réussie et renvoie l'élément extrait de DynamoDB.

  • Pour l'DeleteItemopération, le résolveur AWS AppSync DynamoDB vérifie qu'un élément a été renvoyé par DynamoDB. Si aucun élément n'a été renvoyé, il traite l'opération comme réussie. Dans le cas contraire, il suit la stratégie configurée.

  • Pour l'UpdateItemopération, le résolveur AWS AppSync DynamoDB ne dispose pas de suffisamment d'informations pour déterminer si l'élément actuellement dans DynamoDB correspond au résultat attendu et suit donc la stratégie configurée.

Si l'état actuel de l'objet dans DynamoDB est différent du résultat attendu, le résolveur AWS AppSync DynamoDB suit la stratégie configurée, soit pour rejeter la mutation, soit pour invoquer une fonction Lambda pour déterminer la marche à suivre.

Suivre la stratégie du « rejet »

Lorsque vous suivez Reject cette stratégie, le résolveur AWS AppSync DynamoDB renvoie une erreur pour la mutation, et la valeur actuelle de l'objet dans DynamoDB est également renvoyée dans un data champ de la section de la réponse GraphQL. error L'élément renvoyé par DynamoDB est soumis au modèle de mappage des réponses pour le traduire dans le format attendu par le client, puis il est filtré par le jeu de sélection.

Par exemple, si nous avons la demande de mutation suivante :

mutation { updatePerson(id: 1, name: "Steve", expectedVersion: 1) { Name theVersion } }

Si l'élément renvoyé par DynamoDB ressemble à ce qui suit :

{ "id" : { "S" : "1" }, "name" : { "S" : "Steve" }, "version" : { "N" : 8 } }

Et si le modèle de mappage des réponses ressemble à ce qui suit :

{ "id" : $util.toJson($context.result.id), "Name" : $util.toJson($context.result.name), "theVersion" : $util.toJson($context.result.version) }

La réponse GraphQL se présente comme suit :

{ "data": null, "errors": [ { "message": "The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ)" "errorType": "DynamoDB:ConditionalCheckFailedException", "data": { "Name": "Steve", "theVersion": 8 }, ... } ] }

Notez également que si des champs de l'objet renvoyé sont remplis par d'autres résolveurs et que la mutation a réussi, ils ne seront pas résolus lorsque l'objet sera renvoyé dans la section error.

Suivre la stratégie « personnalisée »

Lorsqu'il suit la Custom stratégie, le résolveur AWS AppSync DynamoDB invoque une fonction Lambda pour décider de la marche à suivre. La fonction Lambda choisit l'une des options suivantes :

  • reject la mutation. Cela indique au résolveur AWS AppSync DynamoDB de se comporter comme si la stratégie configurée l'Rejectétait, renvoyant une erreur pour la mutation et la valeur actuelle de l'objet dans DynamoDB, comme décrit dans la section précédente.

  • discard la mutation. Cela indique au résolveur AWS AppSync DynamoDB d'ignorer silencieusement l'échec de la vérification des conditions et renvoie la valeur dans DynamoDB.

  • retry la mutation. Cela indique au résolveur AWS AppSync DynamoDB de réessayer la mutation avec un nouveau document de mappage de requêtes.

Requête d'appel Lambda

Le résolveur AWS AppSync DynamoDB invoque la fonction Lambda spécifiée dans le. lambdaArn Il utilise le même service-role-arn que celui configuré sur la source de données. La charge utile de l'appel a la structure suivante :

{ "arguments": { ... }, "requestMapping": {... }, "currentValue": { ... }, "resolver": { ... }, "identity": { ... } }

Les champs sont définis comme suit :

arguments

Arguments de la mutation GraphQL. Ce sont les mêmes arguments que ceux disponibles pour le document de mappage des demandes dans $context.arguments.

requestMapping

Document de mappage des demandes pour cette opération.

currentValue

Valeur actuelle de l'objet dans DynamoDB.

resolver

Informations sur le AWS AppSync résolveur.

identity

Informations sur l'appelant. Ce sont les mêmes informations que celles disponibles pour le document de mappage des demandes dans $context.identity.

Exemple complet de la charge utile :

{ "arguments": { "id": "1", "name": "Steve", "expectedVersion": 1 }, "requestMapping": { "version" : "2017-02-28", "operation" : "PutItem", "key" : { "id" : { "S" : "1" } }, "attributeValues" : { "name" : { "S" : "Steve" }, "version" : { "N" : 2 } }, "condition" : { "expression" : "version = :expectedVersion", "expressionValues" : { ":expectedVersion" : { "N" : 1 } }, "equalsIgnore": [ "version" ] } }, "currentValue": { "id" : { "S" : "1" }, "name" : { "S" : "Steve" }, "version" : { "N" : 8 } }, "resolver": { "tableName": "People", "awsRegion": "us-west-2", "parentType": "Mutation", "field": "updatePerson", "outputType": "Person" }, "identity": { "accountId": "123456789012", "sourceIp": "x.x.x.x", "user": "AIDAAAAAAAAAAAAAAAAAA", "userArn": "arn:aws:iam::123456789012:user/appsync" } }

Réponse à l'appel de Lambda

La fonction Lambda peut inspecter la charge utile d'appel et appliquer n'importe quelle logique métier pour décider de la manière dont le résolveur DynamoDB doit gérer AWS AppSync la panne. Il existe trois options pour gérer l'échec de vérification de la condition :

  • reject la mutation. La charge utile de la réponse pour cette option doit avoir cette structure :

    { "action": "reject" }

    Cela indique au résolveur AWS AppSync DynamoDB de se comporter comme si la stratégie configurée l'Rejectétait, renvoyant une erreur pour la mutation et la valeur actuelle de l'objet dans DynamoDB, comme décrit dans la section ci-dessus.

  • discard la mutation. La charge utile de la réponse pour cette option doit avoir cette structure :

    { "action": "discard" }

    Cela indique au résolveur AWS AppSync DynamoDB d'ignorer silencieusement l'échec de la vérification des conditions et renvoie la valeur dans DynamoDB.

  • retry la mutation. La charge utile de la réponse pour cette option doit avoir cette structure :

    { "action": "retry", "retryMapping": { ... } }

    Cela indique au résolveur AWS AppSync DynamoDB de réessayer la mutation avec un nouveau document de mappage de requêtes. La structure de retryMapping cette section dépend de l'opération DynamoDB et constitue un sous-ensemble du document complet de mappage des demandes pour cette opération.

    Pour PutItem, la section retryMapping a la structure suivante. Pour une description du attributeValues champ, voir PutItem.

    { "attributeValues": { ... }, "condition": { "equalsIgnore" = [ ... ], "consistentRead" = true } }

    Pour UpdateItem, la section retryMapping a la structure suivante. Pour une description de update cette section, voir UpdateItem.

    { "update" : { "expression" : "someExpression" "expressionNames" : { "#foo" : "foo" }, "expressionValues" : { ":bar" : ... typed value } }, "condition": { "consistentRead" = true } }

    Pour DeleteItem, la section retryMapping a la structure suivante.

    { "condition": { "consistentRead" = true } }

    Il n'y a aucun moyen de spécifier une autre opération ou une autre clé sur laquelle travailler. Le résolveur AWS AppSync DynamoDB autorise uniquement les tentatives de la même opération sur le même objet. D'autre part, la section condition ne permet pas de spécifier un conditionalCheckFailedHandler. Si la nouvelle tentative échoue, le résolveur AWS AppSync DynamoDB suit la stratégie. Reject

Voici un exemple de fonction Lambda pour traiter une demande PutItem qui a échoué. La logique métier s'adresse à celui qui effectue l'appel. S'il a été créé parjeffTheAdmin, il réessaie la demande en mettant à jour le version et à expectedVersion partir de l'élément actuellement présent dans DynamoDB. Dans le cas contraire, il rejette la mutation.

exports.handler = (event, context, callback) => { console.log("Event: "+ JSON.stringify(event)); // Business logic goes here. var response; if ( event.identity.user == "jeffTheAdmin" ) { response = { "action" : "retry", "retryMapping" : { "attributeValues" : event.requestMapping.attributeValues, "condition" : { "expression" : event.requestMapping.condition.expression, "expressionValues" : event.requestMapping.condition.expressionValues } } } response.retryMapping.attributeValues.version = { "N" : event.currentValue.version.N + 1 } response.retryMapping.condition.expressionValues[':expectedVersion'] = event.currentValue.version } else { response = { "action" : "reject" } } console.log("Response: "+ JSON.stringify(response)) callback(null, response) };