Iniciante5 min de leitura

JSON do DynamoDB & Marshalling

A primeira vez que você lê dados crus da API do DynamoDB, eles não se parecem com o JSON que você colocou. Um objeto puro como {"status": "open", "priority": 3} volta como {"status": {"S": "open"}, "priority": {"N": "3"}}. Cada valor é envolvido em um objeto de uma chave nomeando seu tipo. Esse envolvimento é o JSON do DynamoDB, e converter de e para ele é chamado de marshalling.

Não é ruído — é como o DynamoDB mantém os tipos não ambíguos no fio. Mas isso pega desprevenido qualquer um que espera JSON puro, e escrevê-lo à mão é propenso a erros.

O que é o JSON do DynamoDB?

O JSON do DynamoDB é o formato de transmissão com tag de tipo que o DynamoDB utiliza, onde cada valor é envolvido em um objeto de uma chave que nomeia seu tipo — {"S": "open"} para uma string, {"N": "3"} para um número. Converter JSON puro para esse formato (e de volta) é chamado de marshalling. Ele mantém os tipos sem ambiguidade, já que o JSON puro não consegue expressar sets, binário ou distinguir "3" de 3.

  • O JSON do DynamoDB rotula cada valor com seu tipo{"S": "..."} para uma string, {"N": "..."} para um número, e assim por diante.
  • Marshalling = JSON puro → JSON do DynamoDB. Unmarshalling = o inverso.
  • Números são strings no fio{"N": "3"}, não {"N": 3} — para preservar a precisão.
  • Os rótulos de tipo são o sistema de tipos de dados que você já modela: S, N, B, BOOL, NULL, L, M, SS, NS, BS.
  • Não o escreva à mão. O document client do SDK (ou um conversor) faz o marshalling para você; faça-o manualmente só ao depurar ou construir expressões.

O problema: o JSON puro não é suficiente

O JSON tem exatamente três tipos escalares — string, número, booleano — mais null, arrays e objetos. O DynamoDB tem mais: binário, e três tipos de set (set de string, set de número, set de binário) que o JSON não consegue expressar de jeito nenhum. O JSON também não consegue distinguir uma string "3" de um número 3, ou uma lista de um set.

Então o DynamoDB não pode simplesmente armazenar seu JSON como está — ele precisa do tipo exato de cada valor declarado explicitamente. O descritor de tipo é como ele faz isso, sem perdas, em cada requisição e resposta.

Como a codificação funciona

Cada valor de atributo vira um objeto de uma única chave cuja chave é um descritor de tipo:

DescritorTipoExemplo
SString{"S": "open"}
NNúmero (como string){"N": "3"}
BBinário{"B": "dGV4dA=="}
BOOLBooleano{"BOOL": true}
NULLNulo{"NULL": true}
LLista{"L": [{"S": "a"}, {"N": "1"}]}
MMapa{"M": {"k": {"S": "v"}}}
SS / NS / BSSet de string / número / binário{"SS": ["a", "b"]}

Listas e mapas aninham os mesmos descritores até o fundo, então um item profundamente estruturado fica profundamente envolvido. Os números viajam no fio como strings de propósito — isso permite que o DynamoDB preserve precisão arbitrária que um número JSON (um double IEEE-754) arredondaria silenciosamente. Esses são os mesmos tipos de dados que você modela; o JSON do DynamoDB é apenas a sua forma explícita no fio, definida na referência da API de baixo nível da AWS.

Exemplo prático: uma entrada de log de auditoria

JSON puro que você escreveria no seu app:

{
  "actor": "u-204",
  "action": "ticket.close",
  "ticketId": 8842,
  "tags": ["billing", "urgent"],
  "redacted": false
}

Marshalled para JSON do DynamoDB para a API:

{
  "actor": {"S": "u-204"},
  "action": {"S": "ticket.close"},
  "ticketId": {"N": "8842"},
  "tags": {"SS": ["billing", "urgent"]},
  "redacted": {"BOOL": false}
}

Note as escolhas que o marshaller fez: ticketId virou N com um valor string; tags virou um set de string (SS), não uma lista — uma decisão deliberada, porque um set deduplica e é não ordenado. Se tags deveria ser SS ou L é uma decisão de modelagem que o conversor não pode tomar por você, que é exatamente o motivo pelo qual entender a codificação importa.

Convertendo no DynoTable

Você raramente precisa ler ou escrever isso à mão. Cole JSON puro no conversor de JSON do DynamoDB para fazer o marshalling dele (e de volta), e quando você estiver montando uma requisição, o construtor de expressões do DynamoDB emite o mapa de attribute-value corretamente marshalled junto com a expressão. No próprio app, o DynoTable mostra os itens como valores puros e legíveis e faz o marshalling deles para você na escrita.

DynoTable mostrando um item como valores puros, com o JSON do DynamoDB cru disponível.
DynoTable mostrando um item como valores puros, com o JSON do DynamoDB cru disponível.

Armadilhas e próximos passos

  • Números são strings no JSON do DynamoDB{"N": "3"}. As aspas importam; não emita um número sem aspas.
  • Sets vs listas é uma decisão de modelagem que a codificação torna visível — escolha deliberadamente (veja tipos de dados).
  • Prefira o document client do SDK ao marshalling manual no código do app; reserve o JSON do DynamoDB manual para depuração e expressões.
  • Strings vazias são permitidas em itens mas historicamente pegaram ferramentas desprevenidas — valide casos extremos.

Quer navegar pelos itens como valores puros em vez de decodificar rótulos de tipo a olho? Baixe o DynoTable e trabalhe com seus dados diretamente.

Atualizado