Principiante5 min di lettura

DynamoDB JSON e marshalling

La prima volta che leggi dati grezzi dall'API di DynamoDB, non assomigliano al JSON che hai inserito. Un oggetto semplice come {"status": "open", "priority": 3} torna come {"status": {"S": "open"}, "priority": {"N": "3"}}. Ogni valore è avvolto in un oggetto a una chiave che ne nomina il tipo. Quell'avvolgimento è il DynamoDB JSON, e convertire da e verso di esso si chiama marshalling.

Non è rumore — è il modo in cui DynamoDB mantiene i tipi non ambigui sul filo. Ma manda in confusione chiunque si aspetti JSON semplice, e scriverlo a mano è soggetto a errori.

Cos'è il DynamoDB JSON?

Il DynamoDB JSON è il formato wire con tag di tipo usato da DynamoDB, dove ogni valore è avvolto in un oggetto a una chiave che ne nomina il tipo — {"S": "open"} per una stringa, {"N": "3"} per un numero. La conversione da e verso questo formato si chiama marshalling. Mantiene i tipi non ambigui, poiché il JSON semplice non può esprimere set, binari o la differenza tra "3" e 3.

  • Il DynamoDB JSON marca ogni valore con il suo tipo{"S": "..."} per una stringa, {"N": "..."} per un numero, e così via.
  • Marshalling = JSON semplice → DynamoDB JSON. Unmarshalling = il contrario.
  • I numeri sono stringhe sul filo{"N": "3"}, non {"N": 3} — per preservare la precisione.
  • I tag di tipo sono il sistema di tipi di dato con cui già modelli: S, N, B, BOOL, NULL, L, M, SS, NS, BS.
  • Non scriverlo a mano. Il document client dell'SDK (o un convertitore) fa il marshalling per te; fallo manualmente solo durante il debug o la costruzione di espressioni.

Il problema: il JSON semplice non basta

Il JSON ha esattamente tre tipi scalari — stringa, numero, booleano — più null, array e oggetti. DynamoDB ne ha di più: binario, e tre tipi set (string set, number set, binary set) che il JSON non può esprimere affatto. Il JSON inoltre non sa distinguere una stringa "3" da un numero 3, né una lista da un set.

Quindi DynamoDB non può semplicemente memorizzare il tuo JSON così com'è — ha bisogno che il tipo esatto di ogni valore sia dichiarato esplicitamente. Il descrittore di tipo è il modo in cui lo fa, senza perdite, su ogni richiesta e risposta.

Come funziona la codifica

Ogni valore di attributo diventa un oggetto a chiave singola la cui chiave è un descrittore di tipo:

DescrittoreTipoEsempio
SStringa{"S": "open"}
NNumero (come stringa){"N": "3"}
BBinario{"B": "dGV4dA=="}
BOOLBooleano{"BOOL": true}
NULLNull{"NULL": true}
LLista{"L": [{"S": "a"}, {"N": "1"}]}
MMappa{"M": {"k": {"S": "v"}}}
SS / NS / BSSet di stringhe / numeri / binari{"SS": ["a", "b"]}

Liste e mappe annidano gli stessi descrittori fino in fondo, quindi un item dalla struttura profonda diventa profondamente avvolto. I numeri viaggiano sul filo come stringhe di proposito — permette a DynamoDB di preservare una precisione arbitraria che un numero JSON (un double IEEE-754) arrotonderebbe silenziosamente. Questi sono gli stessi tipi di dato con cui modelli; il DynamoDB JSON è solo la loro forma esplicita sul filo, definita nel riferimento API low-level di AWS.

Esempio pratico: una voce di audit log

Il JSON semplice che scriveresti nella tua app:

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

Sottoposto a marshalling in DynamoDB JSON per l'API:

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

Nota le scelte fatte dal marshaller: ticketId è diventato N con un valore stringa; tags è diventato un string set (SS), non una lista — una decisione deliberata, perché un set deduplica ed è non ordinato. Se tags debba essere SS o L è una scelta di modellazione che il convertitore non può fare per te, ed è esattamente il motivo per cui capire la codifica conta.

Convertire in DynoTable

Raramente hai bisogno di leggere o scrivere questo a mano. Incolla JSON semplice nel Convertitore DynamoDB JSON per farne il marshalling (e viceversa), e quando assembli una richiesta, il DynamoDB Expression Builder emette la mappa di attribute-value correttamente sottoposta a marshalling accanto all'espressione. Nell'app stessa, DynoTable mostra gli item come valori semplici e leggibili e li sottopone a marshalling per te in scrittura.

DynoTable che mostra un item come valori semplici, con il DynamoDB JSON grezzo disponibile.
DynoTable che mostra un item come valori semplici, con il DynamoDB JSON grezzo disponibile.

Trappole e prossimi passi

  • I numeri sono stringhe nel DynamoDB JSON{"N": "3"}. Le virgolette contano; non emettere un numero nudo.
  • Set vs liste è una decisione di modellazione che la codifica rende visibile — scegli deliberatamente (vedi tipi di dato).
  • Preferisci il document client dell'SDK al marshalling manuale nel codice dell'app; riserva il DynamoDB JSON manuale per il debug e le espressioni.
  • Le stringhe vuote sono permesse negli item ma storicamente hanno mandato in tilt il tooling — convalida i casi limite.

Vuoi navigare gli item come valori semplici invece di decodificare i tag di tipo a occhio? Scarica DynoTable e lavora con i tuoi dati direttamente.

Aggiornato