As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
Quando objetos sofrem mutação no DynamoDB usando as operações PutItem
, UpdateItem
e DeleteItem
do DynamoDB, opcionalmente, é possível especificar uma expressão de condição que controla se a solicitação deve ser bem-sucedida ou não, com base no estado do objeto que já está no DynamoDB antes que a operação seja realizada.
A função AWS AppSync DynamoDB permite que uma expressão de condição seja especificada PutItem
emUpdateItem
,, DeleteItem
e solicite objetos, além de uma estratégia a ser seguida se a condição falhar e o objeto não for atualizado.
Exemplo 1
O objeto de solicitação PutItem
a seguir não tem uma expressão de condição. Como resultado, ele coloca um item no DynamoDB mesmo se um item com a mesma chave já existir, sobrescrevendo o item existente.
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),
};
}
Exemplo 2
O seguinte objeto PutItem
possui uma expressão de condição que permite que a operação seja bem-sucedida somente se um item com a mesma chave não existir no 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)" }
};
}
Por padrão, se a verificação da condição falhar, a função AWS AppSync DynamoDB fornecerá um erro para a mutação.
No entanto, a função AWS AppSync DynamoDB oferece alguns recursos adicionais para ajudar os desenvolvedores a lidar com alguns casos extremos comuns:
-
Se AWS AppSync as funções do DynamoDB conseguirem determinar que o valor atual no DynamoDB corresponde ao resultado desejado, ela tratará a operação como se tivesse sido bem-sucedida de qualquer maneira.
-
Em vez de retornar um erro, você pode configurar a função para invocar uma função Lambda personalizada para decidir como a função do AWS AppSync DynamoDB deve lidar com a falha.
Isso é descrito com mais detalhes na seção Tratamento de uma falha de verificação da condição.
Especificação de uma condição
Os objetos da solicitação PutItem
, UpdateItem
e DeleteItem
permitem que uma seção condition
opcional seja especificada. Se omitida, nenhuma verificação de condição é feita. Se especificada, a condição deve ser verdadeira para que a operação seja bem-sucedida.
A seção condition
tem a seguinte estrutura:
type ConditionCheckExpression = {
expression: string;
expressionNames?: { [key: string]: string};
expressionValues?: { [key: string]: any};
equalsIgnore?: string[];
consistentRead?: boolean;
conditionalCheckFailedHandler?: {
strategy: 'Custom' | 'Reject';
lambdaArn?: string;
};
};
Os campos a seguir especificam a condição:
-
expression
-
A própria expressão de atualização. Para obter mais informações sobre como escrever expressões condicionais, consulte a documentação do ConditionExpressions DynamoDB. Esse campo deve ser especificado.
-
expressionNames
-
As substituições para espaços reservados de nome do atributo da expressão, na forma de pares de chave/valor. A chave corresponde a um espaço reservado de nome usado na expressão e o valor deve ser uma string que corresponde ao nome do atributo do item no DynamoDB. Esse campo é opcional e deve ser preenchido apenas por substituições para espaços reservados de nome do atributo da expressão usados na expressão.
-
expressionValues
-
As substituições para espaços reservados de valor do atributo da expressão, na forma de pares chave-valor. A chave corresponde a um espaço reservado de valor usado na expressão e o valor deve ser um valor digitado. Para obter mais informações sobre como especificar um "valor digitado", consulte Sistema de tipo (Mapeamento de solicitação). Isso deve ser especificado. Esse campo é opcional e deve ser preenchido apenas por substituições para espaços reservados de valor do atributo da expressão usados na expressão.
Os campos restantes informam à função do AWS AppSync DynamoDB como lidar com uma falha na verificação de condição:
-
equalsIgnore
-
Quando uma verificação de condição falha ao usar a
PutItem
operação, a função do AWS AppSync DynamoDB compara o item atualmente no DynamoDB com o item que ela tentou gravar. Se forem os mesmos, ele tratará a operação como bem-sucedida. Você pode usar oequalsIgnore
campo para especificar uma lista de atributos que AWS AppSync devem ser ignorados ao realizar essa comparação. Por exemplo, se a única diferença era um atributoversion
, ele trata a operação como bem-sucedida. Esse campo é opcional. -
consistentRead
-
Quando uma verificação de condição falha, AWS AppSync obtém o valor atual do item do DynamoDB usando uma leitura altamente consistente. Você pode usar esse campo para fazer com que a função do AWS AppSync DynamoDB use uma leitura eventualmente consistente em vez disso. Esse campo é opcional e usa como padrão
true
. -
conditionalCheckFailedHandler
-
Esta seção permite especificar como a função do AWS AppSync DynamoDB trata uma falha na verificação de condição depois de comparar o valor atual no DynamoDB com o resultado esperado. Esta seção é opcional. Se omitida, o padrão será uma estratégia de
Reject
.-
strategy
-
A estratégia que a função do AWS AppSync DynamoDB adota depois de comparar o valor atual no DynamoDB com o resultado esperado. Esse campo é obrigatório e tem os valores possíveis a seguir:
-
Reject
-
A mutação falha e um erro é adicionado à resposta do GraphQL.
-
Custom
-
A função AWS AppSync DynamoDB invoca uma função Lambda personalizada para decidir como lidar com a falha na verificação da condição. Quando a
strategy
estiver definida comoCustom
, o campolambdaArn
deve conter o ARN da função do Lambda a ser invocada.
-
-
lambdaArn
-
O ARN da função Lambda a ser invocada determina como a função do DynamoDB deve lidar com a falha na verificação da AWS AppSync condição. Esse campo deve ser especificado somente quando
strategy
for definida comoCustom
. Para obter mais informações sobre como usar esse atributo, consulte Tratamento de uma falha de verificação da condição.
-
Tratamento de uma falha de verificação da condição
Quando uma verificação de condição falha, a AWS AppSync função do DynamoDB pode transmitir o erro da mutação e o valor atual do objeto usando o utilitário. util.appendError
No entanto, a função AWS AppSync DynamoDB oferece alguns recursos adicionais para ajudar os desenvolvedores a lidar com alguns casos extremos comuns:
-
Se AWS AppSync as funções do DynamoDB conseguirem determinar que o valor atual no DynamoDB corresponde ao resultado desejado, ela tratará a operação como se tivesse sido bem-sucedida de qualquer maneira.
-
Em vez de retornar um erro, você pode configurar a função para invocar uma função Lambda personalizada para decidir como a função do AWS AppSync DynamoDB deve lidar com a falha.
O fluxograma para esse processo é:

Verificação do resultado desejado
Quando a verificação da condição falha, a função do AWS AppSync DynamoDB executa uma solicitação do GetItem
DynamoDB para obter o valor atual do item do DynamoDB. Por padrão, ele usa uma leitura fortemente consistente, mas isso pode ser configurado usando o campo consistentRead
no bloco condition
e compará-lo com o resultado esperado:
-
Para a
PutItem
operação, a função AWS AppSync DynamoDB compara o valor atual com o que ela tentou gravar, excluindo quaisquer atributos listados na comparação.equalsIgnore
Se os itens forem os mesmos, ele tratará a operação como bem-sucedida e retornará o item recuperado do DynamoDB. Caso contrário, ele seguirá a estratégia configurada.Por exemplo, se o objeto da solicitação
PutItem
se parecer com o seguinte: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'] } }; }
E o item que está atualmente no DynamoDB se parecer com o seguinte:
{ "id" : { "S" : "1" }, "name" : { "S" : "Steve" }, "version" : { "N" : 8 } }
A AWS AppSync função do DynamoDB compararia o item que tentou gravar com o valor atual, verificaria que a única diferença era
version
o campo, mas, como está configurada para ignorarversion
o campo, ela considera a operação bem-sucedida e retorna o item que foi recuperado do DynamoDB. -
Para a
DeleteItem
operação, a função do AWS AppSync DynamoDB verifica se um item foi retornado do DynamoDB. Se nenhum item foi retornado, ele tratará a operação como bem-sucedida. Caso contrário, ele seguirá a estratégia configurada. -
Para a
UpdateItem
operação, a função do AWS AppSync DynamoDB não tem informações suficientes para determinar se o item atualmente no DynamoDB corresponde ao resultado esperado e, portanto, segue a estratégia configurada.
Se o estado atual do objeto no DynamoDB for diferente do resultado esperado, a função do AWS AppSync DynamoDB segue a estratégia configurada para rejeitar a mutação ou invocar uma função Lambda para determinar o que fazer a seguir.
Seguir a estratégia "Rejeitar"
Ao seguir a Reject
estratégia, a função AWS AppSync DynamoDB retorna um erro para a mutação.
Por exemplo, considere a solicitação de mutação a seguir:
mutation {
updatePerson(id: 1, name: "Steve", expectedVersion: 1) {
Name
theVersion
}
}
Se o item retornado do DynamoDB for semelhante ao seguinte:
{
"id" : { "S" : "1" },
"name" : { "S" : "Steve" },
"version" : { "N" : 8 }
}
E o manipulador de resposta da função tem a seguinte aparência:
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
}
A resposta do GraphQL é semelhante à seguinte:
{
"data": null,
"errors": [
{
"message": "The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ)"
"errorType": "DynamoDB:ConditionalCheckFailedException",
...
}
]
}
Além disso, se qualquer campo no objeto retornado for preenchido por outros resolvedores e a mutação foi bem-sucedida, eles não serão resolvidos quando o objeto for retornado na seção error
.
Seguir a estratégia "Personalizada"
Ao seguir a Custom
estratégia, a função do AWS AppSync DynamoDB invoca uma função Lambda para decidir o que fazer em seguida. A Função Lambda escolhe um destas opções a seguir:
-
reject
a mutação. Isso faz com que a AWS AppSync função do DynamoDB se comporte como se a estratégia configuradaReject
fosse, retornando um erro para a mutação e o valor atual do objeto no DynamoDB, conforme descrito na seção anterior. -
discard
a mutação. Isso faz com que a função do AWS AppSync DynamoDB ignore silenciosamente a falha na verificação da condição e retorne o valor no DynamoDB. -
retry
a mutação. Isso faz com que a AWS AppSync função do DynamoDB repita a mutação com um novo objeto de solicitação.
A solicitação de invocação do Lambda
A função AWS AppSync DynamoDB invoca a função Lambda especificada no. lambdaArn
Ele usa o mesmo service-role-arn
configurado na fonte de dados. A carga da invocação tem a seguinte estrutura:
{
"arguments": { ... },
"requestMapping": {... },
"currentValue": { ... },
"resolver": { ... },
"identity": { ... }
}
Os campos são definidos da seguinte forma:
-
arguments
-
Os argumentos da mutação do GraphQL. Isso é o mesmo que os argumentos disponíveis para o objeto da solicitação em
context.arguments
. -
requestMapping
-
O objeto de solicitação para essa operação.
-
currentValue
-
O valor atual do objeto no DynamoDB.
-
resolver
-
Informações sobre o AWS AppSync resolvedor ou a função.
-
identity
-
Informações sobre o chamador. Isso é o mesmo que as informações de identidade disponíveis para o objeto da solicitação em
context.identity
.
Um exemplo completo da carga:
{
"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"
}
}
A resposta de invocação do Lambda
A função Lambda pode inspecionar a carga de invocação e aplicar qualquer lógica de negócios para decidir como a função do DynamoDB deve lidar com a falha AWS AppSync . Existem três opções para tratamento da falha de verificação da condição:
-
reject
a mutação. A carga da resposta para essa opção deve ter a seguinte estrutura:{ "action": "reject" }
Isso faz com que a AWS AppSync função do DynamoDB se comporte como se a estratégia configurada
Reject
fosse, retornando um erro para a mutação e o valor atual do objeto no DynamoDB, conforme descrito na seção acima. -
discard
a mutação. A carga da resposta para essa opção deve ter a seguinte estrutura:{ "action": "discard" }
Isso faz com que a função do AWS AppSync DynamoDB ignore silenciosamente a falha na verificação da condição e retorne o valor no DynamoDB.
-
retry
a mutação. A carga da resposta para essa opção deve ter a seguinte estrutura:{ "action": "retry", "retryMapping": { ... } }
Isso faz com que a AWS AppSync função do DynamoDB repita a mutação com um novo objeto de solicitação. A estrutura da seção
retryMapping
depende da operação do DynamoDB e é um subconjunto do objeto da solicitação completo para essa operação.Em
PutItem
, a seçãoretryMapping
tem a seguinte estrutura. Para obter uma descrição doattributeValues
campo, consulte PutItem.{ "attributeValues": { ... }, "condition": { "equalsIgnore" = [ ... ], "consistentRead" = true } }
Em
UpdateItem
, a seçãoretryMapping
tem a seguinte estrutura. Para obter uma descrição daupdate
seção, consulte UpdateItem.{ "update" : { "expression" : "someExpression" "expressionNames" : { "#foo" : "foo" }, "expressionValues" : { ":bar" : ... typed value } }, "condition": { "consistentRead" = true } }
Em
DeleteItem
, a seçãoretryMapping
tem a seguinte estrutura.{ "condition": { "consistentRead" = true } }
Não há como especificar uma operação ou chave diferente na qual trabalhar. A função AWS AppSync DynamoDB só permite novas tentativas da mesma operação no mesmo objeto. Além disso, a seção
condition
não permite que umconditionalCheckFailedHandler
seja especificado. Se a nova tentativa falhar, a função do AWS AppSync DynamoDB segue a estratégia.Reject
Veja aqui um exemplo de função do Lambda para lidar com uma solicitação PutItem
com falha. A lógica de negócios analisa quem fez a chamada. Se foi feita pelo jeffTheAdmin
, ela tentará novamente a solicitação, atualizando version
e expectedVersion
do item atualmente no DynamoDB. Caso contrário, ela rejeitará a mutação.
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)
};