UpdateItem do DynamoDB em Node.js (AWS SDK v3)
O cliente de baixo nível da v3 fala DynamoDB JSON nas duas direções, o que significa que todo número que você envia e todo número que recebe de volta é uma string. Isso não é um defeito; é a única forma de um número de 38 dígitos do DynamoDB sobreviver a uma linguagem cujo único tipo numérico é um double. É também onde estão os bugs.
Código
import {DynamoDBClient, UpdateItemCommand} from '@aws-sdk/client-dynamodb';
const client = new DynamoDBClient({region: 'us-east-1'});
const command = new UpdateItemCommand({
TableName: 'Music',
Key: {
Artist: {S: 'Arturo Sandoval'},
SongTitle: {S: 'Cubano Chant'}
},
UpdateExpression: 'SET #upd0 = :updValue0, #upd1 = :updValue1 ADD #upd2 :updValue2',
ExpressionAttributeNames: {
'#upd0': 'Genre',
'#upd1': 'Year',
'#upd2': 'Awards'
},
ExpressionAttributeValues: {
':updValue0': {S: 'Latin Jazz'},
':updValue1': {N: '1994'},
':updValue2': {N: '1'}
},
ReturnValues: 'ALL_NEW'
});
const response = await client.send(command);
console.log(response.Attributes); // the item after the updateContra um item que não tinha Genre nem Awards, o response.Attributes volta assim:
{"Artist":{"S":"Arturo Sandoval"},"Awards":{"N":"1"},"Genre":{"S":"Latin Jazz"},"Year":{"N":"1994"},"SongTitle":{"S":"Cubano Chant"}}typeof response.Attributes.Awards.N é "string", então response.Attributes.Awards.N + 1 resulta em "11". Nada lança erro, nada avisa, e o número errado entra na sua próxima escrita. Faça o parsing na fronteira: Number(response.Attributes.Awards.N).
Explicação
A expressão é uma string simples, e a v3 não vai verificá-la. O
UpdateItemCommandvalida o formato do objeto de entrada, nunca a gramática dentro deUpdateExpression, então um erro de digitação é uma ida e volta e um 400. A gramática está em expressões de atualização;ADD #upd2 :updValue2é o incremento atômico, e adicionarConditionExpression: 'attribute_exists(Artist)'faz a chamada ser só-atualização em vez de upsert.ReturnValues: 'UPDATED_NEW'costuma ser o que você quer. A mesma atualização retorna{"Awards":{"N":"2"}}e nada mais. OALL_NEWmanda o item inteiro de volta a cada chamada, o que, em um item gordo, é banda que você paga para ler um contador.$metadataé o canal fora de banda da v3:{"httpStatusCode":200,"requestId":"...","attempts":1,"totalRetryDelay":0}. Oattemptsé a resposta honesta para "isso foi retentado?", o que importa quando você está raciocinando sobre se uma escrita não idempotente rodou duas vezes.ValidationExceptionnão é uma classe que você possa capturar, só umnameque você pode comparar. Um alias faltando volta comoerr.name === 'ValidationException'comerr.messageigual aInvalid UpdateExpression: Attribute name is a reserved keyword; reserved keyword: Year.O document client é a outra troca. O
@aws-sdk/lib-dynamodbrecebe valores nativos de JS e faz unmarshal da resposta, ao custo daquela segurança das strings. Omarshall({awards: 9007199254740993})do@aws-sdk/util-dynamodbrecusa de imediato:Number 9007199254740992 is greater than Number.MAX_SAFE_INTEGER. Use NumberValue from @aws-sdk/lib-dynamodb.Olhe bem para o número nessa mensagem. Ele termina em
2, não no3que foi escrito no literal: o JavaScript já o havia arredondado antes de o SDK sequer vê-lo. O cliente de baixo nível deste trecho não pode ter esse problema, porque{N: '9007199254740993'}é texto até chegar na rede.
O que uma condição que falha te entrega
Adicione ReturnValuesOnConditionCheckFailure: 'ALL_OLD' à entrada e o erro lançado carrega o item que te venceu:
name: ConditionalCheckFailedException | message: "The conditional request failed" | http: 400
err.Item: {"Artist":{"S":"Arturo Sandoval"},"Awards":{"N":"2"},"Year":{"N":"1994"},"SongTitle":{"S":"Cubano Chant"},"Genre":{"S":"Latin Jazz"}}O err.Item é DynamoDB JSON cru, não importa qual cliente o lançou, e ele é grátis. Sem ele, a forma honesta de descobrir por que uma atualização com concorrência otimista falhou é um GetItem de acompanhamento que custa uma leitura e já pode estar desatualizado de novo.
O conversor de DynamoDB JSON transforma esse payload em um objeto JS simples e de volta, que é a forma mais rápida de montar um fixture a partir de um item real. Para tirar esse item de uma tabela ao vivo, para começar, baixe o DynoTable.
Guias relacionados
- Expressões de atualização do DynamoDB —
SET,ADD,REMOVE,DELETEe idiomatismos. - Entendendo o ReturnValues — o que cada opção de
ReturnValueste dá. - "Attribute name is a reserved keyword" — por que o mapa de aliases aqui não é opcional.
- Erros de sintaxe "Invalid UpdateExpression" — os erros comuns de sintaxe de SET/ADD, decodificados.
Referências
- UpdateItem — Amazon DynamoDB API Reference
- UpdateItemCommand — AWS SDK for JavaScript v3 Reference
- Update expressions — Amazon DynamoDB Developer Guide
Verificado pela última vez em 2026-07-28 contra a documentação oficial da AWS vinculada acima.