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 conditionnelles
Lorsque vous mutez des objets dans DynamoDB à l'aide des opérations PutItemUpdateItem, et DeleteItem DynamoDB, vous pouvez éventuellement spécifier une expression de condition qui contrôle 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.
La fonction AWS AppSync DynamoDB permet de spécifier une expression de condition dans des objets et de DeleteItem demander des objets PutItemUpdateItem, ainsi qu'une stratégie à suivre si la condition échoue et que l'objet n'a pas été mis à jour.
Exemple 1
L'objet de PutItem requête suivant ne possède pas d'expression de condition. Par conséquent, il place un élément dans DynamoDB même si un élément avec la même clé existe déjà, écrasant ainsi l'élément existant.
import { util } from '@aws-appsync/utils'; export function request(ctx) { const { foo, bar, ...values} = ctx.args return { operation: 'PutItem', key: util.dynamodb.toMapValues({foo, bar}), attributeValues: util.dynamodb.toMapValues(values), }; }
Exemple 2
L'PutItemobjet suivant possède une expression de condition qui permet à l'opération de réussir uniquement si aucun élément avec la même clé n'existe dans DynamoDB.
import { util } from '@aws-appsync/utils'; export function request(ctx) { const { foo, bar, ...values} = ctx.args return { operation: 'PutItem', key: util.dynamodb.toMapValues({foo, bar}), attributeValues: util.dynamodb.toMapValues(values), condition: { expression: "attribute_not_exists(id)" } }; }
Par défaut, si la vérification de l'état échoue, la fonction AWS AppSync DynamoDB génère une erreur pour la mutation.
Cependant, la fonction AWS AppSync DynamoDB propose des fonctionnalités supplémentaires destinées à aider les développeurs à gérer certains cas extrêmes courants :
-
Si les fonctions AWS AppSync DynamoDB peuvent déterminer que la valeur actuelle de DynamoDB correspond au résultat souhaité, elles traitent l'opération comme si elle avait quand même réussi.
-
Au lieu de renvoyer une erreur, vous pouvez configurer la fonction pour appeler une fonction Lambda personnalisée afin de décider de la manière dont la fonction AWS AppSync DynamoDB doit gérer l'échec.
Elles sont décrites plus en détail dans la section Gestion d'un échec de vérification d'état.
Pour plus d'informations sur les expressions de conditions DynamoDB, consultez la documentation DynamoDB ConditionExpressions .
Spécifier une condition
Les objets PutItemUpdateItem,, et DeleteItem request permettent tous de spécifier une condition section 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 :
type ConditionCheckExpression = { expression: string; expressionNames?: { [key: string]: string}; expressionValues?: { [key: string]: any}; equalsIgnore?: string[]; consistentRead?: boolean; conditionalCheckFailedHandler?: { strategy: 'Custom' | 'Reject'; lambdaArn?: string; }; };
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 DynamoDB ConditionExpressions . 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 plus d'informations sur la façon de spécifier une « valeur typée », voir Système de types (mappage des demandes). 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 à la fonction 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, la fonction 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 utiliserequalsIgnorece champ pour spécifier une liste d'attributs AWS AppSync à ignorer lors de cette comparaison. Par exemple, si la seule différence est unversionattribut, l'opération est traitée comme si elle avait réussi. Ce champ est facultatif. -
consistentRead -
En cas d'échec d'une vérification de condition, AWS AppSync obtient la valeur actuelle de l'élément auprès de DynamoDB en utilisant une lecture très cohérente. Vous pouvez utiliser ce champ pour indiquer à la fonction AWS AppSync DynamoDB d'utiliser une lecture éventuellement cohérente à la place. Ce champ est facultatif et contient
truepar défaut. -
conditionalCheckFailedHandler -
Cette section vous permet de spécifier comment la fonction AWS AppSync DynamoDB traite un échec de vérification d'état 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 la fonction AWS AppSync DynamoDB après avoir comparé la valeur actuelle de DynamoDB au résultat attendu. Ce champ est obligatoire et les valeurs suivantes sont possibles :
-
Reject -
La mutation échoue et une erreur est ajoutée à la réponse GraphQL.
-
Custom -
La fonction AWS AppSync DynamoDB invoque une fonction Lambda personnalisée pour décider de la manière de gérer l'échec de la vérification de condition. Lorsque la
strategyest définie surCustom, le champlambdaArndoit contenir l'ARN de la fonction Lambda à appeler.
-
-
lambdaArn -
L'ARN de la fonction Lambda à invoquer détermine la manière dont la fonction AWS AppSync DynamoDB doit gérer l'échec de la vérification de condition. Ce champ doit être spécifié uniquement lorsque
strategyest défini surCustom. Pour plus d'informations sur l'utilisation de cette fonctionnalité, consultez la section Gestion d'un échec de vérification de condition.
-
Gestion d'un échec de vérification d'état
Lorsqu'une vérification de condition échoue, la fonction AWS AppSync DynamoDB peut transmettre l'erreur associée à la mutation et la valeur actuelle de l'objet à l'util.appendErroraide de cet utilitaire. Cependant, la fonction AWS AppSync DynamoDB propose des fonctionnalités supplémentaires destinées à aider les développeurs à gérer certains cas extrêmes courants :
-
Si les fonctions AWS AppSync DynamoDB peuvent déterminer que la valeur actuelle de DynamoDB correspond au résultat souhaité, elles traitent l'opération comme si elle avait quand même réussi.
-
Au lieu de renvoyer une erreur, vous pouvez configurer la fonction pour appeler une fonction Lambda personnalisée afin de décider de la manière dont la fonction AWS AppSync DynamoDB doit gérer l'échec.
Le diagramme de ce processus est le suivant :
Vérifier le résultat souhaité
Lorsque la vérification de l'état échoue, la fonction AWS AppSync DynamoDB exécute une requête GetItem 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, la fonction AWS AppSync DynamoDB compare la valeur actuelle à celle qu'elle a tenté d'écrire, en excluant les attributs répertoriésequalsIgnorede la comparaison. Si les éléments sont identiques, l'opération est considérée 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 l'objet de la
PutItemrequête ressemble à ce qui suit :import { util } from '@aws-appsync/utils'; export function request(ctx) { const { id, name, version} = ctx.args return { operation: 'PutItem', key: util.dynamodb.toMapValues({foo, bar}), attributeValues: util.dynamodb.toMapValues({ name, version: version+1 }), condition: { expression: "version = :expectedVersion", expressionValues: util.dynamodb.toMapValues({':expectedVersion': version}), equalsIgnore: ['version'] } }; }Et si l'élément actuellement dans DynamoDB ressemble à ce qui suit :
{ "id" : { "S" : "1" }, "name" : { "S" : "Steve" }, "version" : { "N" : 8 } }La fonction AWS AppSync DynamoDB comparerait l'élément qu'elle a essayé d'écrire à la valeur actuelle, en constatant que la seule différence était le
versionchamp, mais comme elle est configurée pour ignorer leversionchamp, elle considère l'opération comme réussie et renvoie l'élément extrait de DynamoDB. -
Pour l'
DeleteItemopération, la fonction 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, la fonction AWS AppSync DynamoDB ne dispose pas de suffisamment d'informations pour déterminer si l'élément actuellement présent 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, la fonction 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 de « rejet »
Lorsque vous suivez la Reject stratégie, la fonction AWS AppSync DynamoDB renvoie une erreur pour la mutation.
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 le gestionnaire de réponse de la fonction ressemble à ce qui suit :
import { util } from '@aws-appsync/utils'; export function response(ctx) { const { version, ...values } = ctx.result; const result = { ...values, theVersion: version }; if (ctx.error) { if (error) { return util.appendError(error.message, error.type, result, null); } } return result }
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", ... } ] }
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 »
Lorsque vous suivez la Custom stratégie, la fonction AWS AppSync DynamoDB invoque une fonction Lambda pour décider de la marche à suivre. La fonction Lambda choisit l'une des options suivantes :
-
rejectla mutation. Cela indique à la fonction AWS AppSync DynamoDB de se comporter comme si la stratégie configurée l'étaitReject, renvoyant une erreur pour la mutation et la valeur actuelle de l'objet dans DynamoDB, comme décrit dans la section précédente. -
discardla mutation. Cela indique à la fonction AWS AppSync DynamoDB d'ignorer silencieusement l'échec de la vérification de condition et renvoie la valeur dans DynamoDB. -
retryla mutation. Cela indique à la fonction AWS AppSync DynamoDB de réessayer la mutation avec un nouvel objet de requête.
Requête d'appel Lambda
La fonction AWS AppSync DynamoDB appelle 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. C'est le même que les arguments disponibles pour l'objet de requête dans
context.arguments. -
requestMapping -
L'objet de la requête pour cette opération.
-
currentValue -
La valeur actuelle de l'objet dans DynamoDB.
-
resolver -
Informations sur le AWS AppSync résolveur ou la fonction.
-
identity -
Informations sur l'appelant. Il s'agit des mêmes informations d'identité disponibles pour l'objet de la demande 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'invocation et appliquer n'importe quelle logique métier pour décider de la manière dont la fonction AWS AppSync DynamoDB doit gérer la panne. Il existe trois options pour gérer l'échec de vérification de la condition :
-
rejectla mutation. La charge utile de la réponse pour cette option doit avoir cette structure :{ "action": "reject" }Cela indique à la fonction AWS AppSync DynamoDB de se comporter comme si la stratégie configurée renvoyait
Rejectune erreur pour la mutation et la valeur actuelle de l'objet dans DynamoDB, comme décrit dans la section ci-dessus. -
discardla mutation. La charge utile de la réponse pour cette option doit avoir cette structure :{ "action": "discard" }Cela indique à la fonction AWS AppSync DynamoDB d'ignorer silencieusement l'échec de la vérification de condition et renvoie la valeur dans DynamoDB.
-
retryla mutation. La charge utile de la réponse pour cette option doit avoir cette structure :{ "action": "retry", "retryMapping": { ... } }Cela indique à la fonction AWS AppSync DynamoDB de réessayer la mutation avec un nouvel objet de requête. La structure de la
retryMappingsection dépend de l'opération DynamoDB et constitue un sous-ensemble de l'objet de requête complet pour cette opération.Pour
PutItem, la sectionretryMappinga la structure suivante. Pour une description duattributeValueschamp, consultez PutItem.{ "attributeValues": { ... }, "condition": { "equalsIgnore" = [ ... ], "consistentRead" = true } }Pour
UpdateItem, la sectionretryMappinga la structure suivante. Pour une description deupdatecette section, voir UpdateItem.{ "update" : { "expression" : "someExpression" "expressionNames" : { "#foo" : "foo" }, "expressionValues" : { ":bar" : ... typed value } }, "condition": { "consistentRead" = true } }Pour
DeleteItem, la sectionretryMappinga 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. La fonction AWS AppSync DynamoDB permet uniquement de recommencer la même opération sur le même objet. D'autre part, la section
conditionne permet pas de spécifier unconditionalCheckFailedHandler. Si la nouvelle tentative échoue, la fonction 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 depuis l'élément actuellement 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) };