Einsteiger4 Min. Lesezeit

DynamoDB JSON & Marshalling

Wenn du zum ersten Mal Rohdaten aus der DynamoDB-API liest, sieht es nicht aus wie das JSON, das du hineingegeben hast. Ein einfaches Objekt wie {"status": "open", "priority": 3} kommt als {"status": {"S": "open"}, "priority": {"N": "3"}} zurück. Jeder Wert ist in ein Objekt mit einem Key verpackt, das seinen Typ benennt. Diese Verpackung ist DynamoDB JSON, und in sie hinein und aus ihr heraus zu konvertieren heißt Marshalling.

Es ist kein Rauschen — es ist, wie DynamoDB Typen auf der Leitung eindeutig hält. Aber es bringt jeden aus dem Tritt, der reines JSON erwartet, und es von Hand zu schreiben ist fehleranfällig.

Was ist DynamoDB JSON?

DynamoDB JSON ist das typgetaggte Übertragungsformat, das DynamoDB verwendet: Jeder Wert wird in ein Objekt mit einem einzigen Key verpackt, der den Typ benennt — {"S": "open"} für einen String, {"N": "3"} für eine Zahl. Die Konvertierung von reinem JSON in dieses Format (und zurück) nennt sich Marshalling. Das Format hält Typen eindeutig, da reines JSON Sets, Binärdaten oder den Unterschied zwischen "3" und 3 nicht ausdrücken kann.

  • DynamoDB JSON taggt jeden Wert mit seinem Typ{"S": "..."} für einen String, {"N": "..."} für eine Zahl und so weiter.
  • Marshalling = reines JSON → DynamoDB JSON. Unmarshalling = die Umkehrung.
  • Zahlen sind Strings auf der Leitung{"N": "3"}, nicht {"N": 3} — um die Präzision zu wahren.
  • Die Typ-Tags sind das Datentypsystem, mit dem du ohnehin modellierst: S, N, B, BOOL, NULL, L, M, SS, NS, BS.
  • Schreib es nicht von Hand. Der Document Client des SDK (oder ein Konverter) marshallt für dich; tu es manuell nur beim Debuggen oder beim Bauen von Expressions.

Das Problem: reines JSON reicht nicht

JSON hat genau drei Skalar-Arten — String, Zahl, Boolean — plus Null, Arrays und Objekte. DynamoDB hat mehr: Binärdaten und drei Set-Typen (String Set, Number Set, Binary Set), die JSON überhaupt nicht ausdrücken kann. JSON kann auch einen String "3" nicht von einer Zahl 3 unterscheiden, oder eine Liste von einem Set.

Also kann DynamoDB dein JSON nicht einfach so speichern — es braucht den exakten Typ jedes Werts explizit angegeben. Der Typ-Deskriptor ist, wie es das tut, verlustfrei, bei jedem Request und jeder Response.

Wie die Kodierung funktioniert

Jeder Attributwert wird ein Objekt mit einem Key, dessen Key ein Typ-Deskriptor ist:

DeskriptorTypBeispiel
SString{"S": "open"}
NZahl (als String){"N": "3"}
BBinär{"B": "dGV4dA=="}
BOOLBoolean{"BOOL": true}
NULLNull{"NULL": true}
LListe{"L": [{"S": "a"}, {"N": "1"}]}
MMap{"M": {"k": {"S": "v"}}}
SS / NS / BSString- / Number- / Binary-Set{"SS": ["a", "b"]}

Listen und Maps verschachteln dieselben Deskriptoren bis ganz nach unten, sodass ein tief strukturiertes Item tief verpackt wird. Zahlen reisen absichtlich als Strings über die Leitung — das lässt DynamoDB beliebige Präzision wahren, die eine JSON-Zahl (ein IEEE-754-Double) still runden würde. Das sind dieselben Datentypen, mit denen du modellierst; DynamoDB JSON ist nur ihre explizite Form auf der Leitung, definiert in der AWS Low-Level-API-Referenz.

Durchgespieltes Beispiel: ein Audit-Log-Eintrag

Reines JSON, das du in deiner App schreiben würdest:

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

Zu DynamoDB JSON für die API gemarshallt:

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

Beachte die Entscheidungen, die der Marshaller getroffen hat: ticketId wurde zu N mit einem String-Wert; tags wurde zu einem String Set (SS), nicht zu einer Liste — eine bewusste Entscheidung, weil ein Set dedupliziert und ungeordnet ist. Ob tags ein SS oder L sein sollte, ist eine Modellierungsentscheidung, die der Konverter nicht für dich treffen kann, was genau der Grund ist, warum die Kodierung zu verstehen wichtig ist.

Konvertieren in DynoTable

Du musst das selten von Hand lesen oder schreiben. Füge reines JSON in den DynamoDB JSON Converter ein, um es zu marshallen (und zurück), und wenn du einen Request zusammenstellst, gibt der DynamoDB Expression Builder die korrekt gemarshallte Attribute-Value-Map zusammen mit der Expression aus. In der App selbst zeigt DynoTable Items als einfache, lesbare Werte und marshallt sie beim Write für dich.

DynoTable zeigt ein Item als einfache Werte, mit verfügbarem rohem DynamoDB JSON.
DynoTable zeigt ein Item als einfache Werte, mit verfügbarem rohem DynamoDB JSON.

Fallstricke und nächste Schritte

  • Zahlen sind Strings in DynamoDB JSON{"N": "3"}. Anführungszeichen zählen; gib keine nackte Zahl aus.
  • Sets vs. Listen ist eine Modellierungsentscheidung, die die Kodierung sichtbar macht — wähle bewusst (siehe Datentypen).
  • Bevorzuge den SDK Document Client gegenüber Hand-Marshalling im App-Code; reserviere manuelles DynamoDB JSON fürs Debuggen und für Expressions.
  • Leere Strings sind erlaubt in Items, haben aber historisch Tooling aus dem Tritt gebracht — validiere Randfälle.

Willst du Items als einfache Werte durchstöbern, statt Typ-Tags mit dem Auge zu dekodieren? DynoTable herunterladen und direkt mit deinen Daten arbeiten.

Aktualisiert