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:
| Descritor | Tipo | Exemplo |
|---|---|---|
S | String | {"S": "open"} |
N | Número (como string) | {"N": "3"} |
B | Binário | {"B": "dGV4dA=="} |
BOOL | Booleano | {"BOOL": true} |
NULL | Nulo | {"NULL": true} |
L | Lista | {"L": [{"S": "a"}, {"N": "1"}]} |
M | Mapa | {"M": {"k": {"S": "v"}}} |
SS / NS / BS | Set 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.

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.


