Pemula6 menit baca

DynamoDB JSON & Marshalling

Pertama kali membaca data mentah dari DynamoDB API, tidak terlihat seperti JSON Anda masukkan. Objek biasa seperti {"status": "open", "priority": 3} kembali sebagai {"status": {"S": "open"}, "priority": {"N": "3"}}. Setiap nilai dibungkus dalam a objek satu tombol yang memberi nama tipenya. Pembungkusnya adalah DynamoDB JSON, dan diubah menjadi dan dari situ disebut marshalling.

Pembungkusan tersebut adalah cara DynamoDB menjaga agar tipe tetap tidak ambigu pada kabel. Tapi itu tersandung up siapa pun mengharapkan JSON biasa, dan tulisan tangan itu rawan kesalahan.

Apa itu DynamoDB JSON?

DynamoDB JSON adalah format kabel bertanda tipe yang digunakan DynamoDB, di mana setiap nilai dibungkus dalam objek satu kunci yang memberi nama tipenya — {"S": "open"} untuk string, {"N": "3"} untuk angka. Mengonversi JSON biasa ke sana (dan sebaliknya) disebut marshalling. Itu membuat tipenya tetap jelas, karena JSON biasa tidak dapat mengekspresikan himpunan atau biner, dan karena angka DynamoDB menggunakan kabel sebagai string, 3 yang tidak diberi tag akan menjadi ambigu.

  • DynamoDB JSON menandai setiap nilai dengan tipenya{"S": "..."} untuk sebuah string, {"N": "..."} untuk nomor, dan seterusnya.
  • Marshalling = JSON biasa → DynamoDB JSON. Unmarshalling = sebaliknya.
  • Angka adalah string pada kawat{"N": "3"}, bukan {"N": 3} — untuk dipertahankan presisi.
  • Tag tipe adalah sistem tipe data yang sudah Anda modelkan dengan: S, N, B, BOOL, BATAL, L, M, SS, NS, BS.
  • Jangan menulisnya dengan tangan. Klien dokumen SDK (atau konverter) digunakan untuk kamu; lakukan secara manual hanya saat men-debug atau membuat ekspresi.

Masalahnya: JSON biasa saja tidak cukup

JSON memiliki tiga jenis skalar — string, angka, boolean — ditambah null, array, dan objek. DynamoDB memiliki lebih banyak: biner, dan tiga jenis set (rangkaian string, kumpulan angka, set biner) yang JSON tidak dapat ungkapkan sama sekali. Dan karena nomor DynamoDB mengikuti kabel sebagai string, 3 yang tidak diberi tag akan menjadi ambigu — ditambah lagi JSON tidak dapat membedakan daftar dari a mengatur.

Jadi DynamoDB tidak bisa begitu saja menyimpan JSON apa adanya — ia perlu menyatakan tipe persis setiap nilai secara eksplisit. Deskriptor tipe adalah cara melakukan hal itu, tanpa kehilangan, pada setiap permintaan dan tanggapan.

Cara kerja pengkodean

Setiap nilai atribut menjadi objek kunci tunggal yang kuncinya adalah deskriptor tipe:

DeskripsiKetikContoh
STali{"S": "open"}
NNomor (sebagai string){"N": "3"}
BBiner{"B": "dGV4dA=="}
BOOLBoolean{"BOOL": true}
NULLBatal{"NULL": true}
LDaftar{"L": [{"S": "a"}, {"N": "1"}]}
MPeta{"M": {"k": {"S": "v"}}}
SS / NS / BSString / Angka / Himpunan Biner{"SS": ["a", "b"]}

Daftar dan peta menyusun deskriptor yang sama hingga ke bawah, sehingga menjadi item yang sangat terstruktur menjadi terbungkus dalam. Angka-angka sengaja digerakkan sebagai string — hal ini memungkinkan DynamoDB mempertahankan presisi numerik 38 digit penuhnya dibandingkan angka JSON (sebuah IEEE-754 ganda, ~15–17 digit signifikan) akan membulat dengan tenang. Ini sama saja tipe data yang Anda modelkan; DynamoDB JSON hanyalah eksplisitnya formulir on-the-wire, didefinisikan dalam Referensi API tingkat rendah AWS.

Contoh yang berhasil: entri log audit

JSON biasa yang Anda tulis di aplikasi Anda:

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

Dikirim ke DynamoDB JSON untuk API:

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

Perhatikan pilihan di balik item ini: ticketId menjadi N dengan nilai string; tags sebagai rangkaian string (SS), bukan daftar, adalah pilihan pemodelan buatan tangan — a konverter generik yang diberi makan JSON biasa memancarkan L, karena array JSON dipesan dan dapat ulangi, sementara SS melakukan dedupes dan tidak berurutan. Apakah tags harus menjadi SS atau L adalah a panggilan pemodelan yang tidak dapat dibuat oleh konverter untuk Anda, itulah sebabnya memahaminya pengkodean itu penting.

Mengonversi dalam DynoTable

Anda jarang perlu membaca atau menulis ini dengan tangan. Rekatkan JSON biasa ke dalam Konverter DynamoDB JSON untuk menyusunnya (dan sebaliknya), dan saat Anda menyusun permintaan, itu Pembuat ekspresi DynamoDB memancarkan dengan benar menyusun peta nilai atribut di samping ekspresi. Di aplikasi itu sendiri, DynoTable menampilkan item sebagai nilai yang jelas dan mudah dibaca dan menyusunnya untuk Anda saat ditulis.

<gambar kelas="doc-media-placeholder" jenis data="tangkapan layar" data-src="docs/guide-dynamodb-json-marshalling-item-view.png"

DynoTable menampilkan item sebagai nilai biasa, dengan DynamoDB JSON mentah tersedia.

Jebakan + langkah selanjutnya

  • Angka adalah string dalam DynamoDB JSON{"N": "3"}. Mengutip itu penting; jangan memancarkan angka kosong.
  • Kumpulan vs daftar adalah keputusan pemodelan pengkodeannya terlihat — pilih sengaja (lihat tipe data).
  • Lebih memilih klien dokumen SDK daripada menyusun kode aplikasi secara manual; panduan cadangan DynamoDB JSON untuk debugging dan ekspresi.
  • String kosong diperbolehkan untuk atribut non-kunci (sejak 2020) tetapi masih ditolak untuk kunci tabel dan indeks, dan pernah mengalami trip perkakas — memvalidasi kasus edge.

Ingin menelusuri item sebagai nilai biasa alih-alih mendekode tag tipe secara langsung? Unduh DynoTable dan kerjakan data Anda secara langsung.

Klien tingkat rendah vs klien dokumen

SDK AWS menawarkan dua lapisan:

LapisanBentuk masukanSiapa marshal
@aws-sdk/client-dynamodb (tingkat rendah)Peta DynamoDB JSON AttributeValueKode atau pembantu Anda
@aws-sdk/lib-dynamodb (dokumen)Objek JS biasaSDK di send/receive

Kode aplikasi harus default ke klien dokumen untuk PutItem/GetItem. Raih peta tingkat rendah saat Anda menulis tangan perbarui ekspresi atau ketika perpustakaan mengharapkannya nilai atribut yang diketik.

Nilai atribut ekspresi juga disusun

Placeholder ConditionExpression, UpdateExpression, dan FilterExpression (:val, :inc) dipetakan ke nilai yang disusun di ExpressionAttributeValues:

":status": {"S": "open"}
":count": {"N": "1"}

Ketidakcocokan — mengirim "open" tanpa pembungkus S pada klien tingkat rendah — mengembalikan ValidationException. Itu pembuat ekspresi memancarkan peta di sampingnya string ekspresi sehingga placeholder dan tipe tetap selaras.

Atribut nama yang bertabrakan kata-kata yang dicadangkan digunakan ExpressionAttributeNames (#st) sebagai gantinya; alat pemeriksa mengeluarkan alias peta siap ditempel.

Unmarshal kejutan dalam ujian

Kegagalan pengujian umum dari marshalling:

  • Set kosong — DynamoDB menolak SS/NS/BS kosong; hilangkan atributnya sebagai gantinya.
  • Mengambang di N — mengirim "3.14" sebagai string, bukan nomor JSON, melalui kabel.
  • Biner di NodeUint8Array di klien dokumen; base64 dalam JSON mentah.
  • Atribut tidak terdefinisi — klien dokumen menghapus undefined; klien tingkat rendah dapat mengirimkan muatan yang tidak valid.

Saat Lambda mencatat respons API mentah, tempelkan satu item ke dalam Konverter DynamoDB JSON ke JSON biasa yang dapat dibaca sebelum berbeda dengan perlengkapan.

Ukuran dampak pemberian tag

Setiap pembungkus tipe menambahkan byte. Objek datar JSON yang disusun bidang demi bidang tumbuh kira-kira 30–40% bergantung pada nama atribut — yang dipicu oleh inflasi ukuran item dan pembulatan RCU/WCU. Peta besar dengan nama atribut pendek mengamortisasi overhead; bendera boolean kecil masih membayar nama kunci mereka ditambah {"BOOL":true}.

Sebelum memuat item marshal secara massal, periksa total byte di kalkulator ukuran item jadi tulis batch tidak tiba-tiba melewati batas permintaan 16 MB.

Dua tampilan DynoTable

Editor item terus menyusun hal yang tidak terlihat dari hari ke hari — Anda mengedit nilai biasa, dan melakukan marshal saat dikirim. Saat men-debug item produksi yang disalin Log CloudWatch, beralih ke tampilan DynamoDB JSON untuk melihat tag yang tepat, lalu beralih kembali ke Plain JSON untuk diedit. Tindakan ekspor menyalin representasi tiket dan kasus uji.

Diperbarui