Pertukaran data antar program hampir selalu melewati dua jalan yang sama, yaitu format teks yang disepakati bersama pihak lain, atau lapisan serialisasi yang menyimpan objek langsung. Nim menyediakan keduanya di pustaka standar, yaitu modul json untuk dokumen JSON yang dibaca dan ditulis secara eksplisit, serta modul marshal untuk mengubah objek Nim menjadi teks dan sebaliknya tanpa deklarasi tambahan. Topik ini membawa keduanya pada kasus yang sering dijumpai, yaitu mencatat bacaan sensor ke berkas JSON lalu membacanya kembali, dan mengarsipkan sekumpulan objek hasil ujian.
Menulis dan membaca dokumen JSON#
Modul json mewakili dokumen JSON sebagai tipe JsonNode yang dapat berupa objek, larik, string, angka, maupun boolean. Operator %* membangun node dari nilai Nim dengan notasi yang mirip JSON itu sendiri, sehingga struktur dokumen terbaca hampir seperti berkasnya. Program berikut mencatat dua sensor ke berkas catatan.json, membacanya kembali dengan parseJson, lalu menelusuri larik sensor untuk mencetak setiap bacaan.
# catatan_sensor.nim: menulis lalu membaca kembali berkas JSON
import json
type SensorSuhu = object
nama: string
suhu: float
let sensor = [
SensorSuhu(nama: "ruang-server", suhu: 27.5),
SensorSuhu(nama: "ruang-laboratorium", suhu: 24.0),
]
var dokumen = %*{
"perangkat": "pencatat-suhu",
"waktu": "2026-11-04T08:00:00",
"sensor": []
}
for s in sensor:
dokumen["sensor"].add(%*{"nama": s.nama, "suhu": s.suhu})
writeFile("catatan.json", pretty(dokumen))
echo "tercatat: ", len(dokumen["sensor"]), " sensor"
let bacaan = parseJson(readFile("catatan.json"))
echo "perangkat: ", bacaan["perangkat"].getStr()
for s in bacaan["sensor"]:
echo s["nama"].getStr(), " -> ", s["suhu"].getFloat(), " derajat"# kompilasi dan jalankan program catatan sensor JSON
nim c --hints:off -r catatan_sensor.nimtercatat: 2 sensor
perangkat: pencatat-suhu
ruang-server -> 27.5 derajat
ruang-laboratorium -> 24.0 derajatBerkas catatan.json dihasilkan dengan pretty, yaitu pencetak yang menambah indentasi agar dokumen nyaman dibaca manusia, dan berikut isi lengkapnya.
{
"perangkat": "pencatat-suhu",
"waktu": "2026-11-04T08:00:00",
"sensor": [
{
"nama": "ruang-server",
"suhu": 27.5
},
{
"nama": "ruang-laboratorium",
"suhu": 24.0
}
]
}Setiap node membawa kind yang menyatakan wajahnya, dengan nilai seperti JObject, JArray, JString, dan JFloat, sehingga kode yang menghadapi dokumen dari luar dapat memeriksa bentuknya lebih dahulu sebelum mengambil isinya. Pemeriksaan ini menjadi penting ketika dokumen berasal dari pihak lain, karena bidang yang dijanjikan bisa saja tidak hadir atau hadir dalam wajah yang berbeda, dan pemeriksaan kind mengubah kemungkinan itu menjadi percabangan yang tenang.
Akses bidang memakai tanda kurung siku dengan indeks string untuk objek dan bilangan untuk larik, lalu diakhiri pengambil bertipe seperti getStr dan getFloat Pengambil bertipe ini yang menjaga keamanan data, karena node yang seharusnya angka tetapi berisi teks akan memunculkan error yang jelas saat program berjalan, bukan nilai kosong yang berjalan diam.
Selain penelusuran manual, modul json juga memetakan node ke objek Nim yang sudah dinyatakan dengan type melalui proc to, misalnya to[seq[SensorSuhu]](bacaan["sensor"]) menghasilkan kumpulan objek lengkap dengan bidangnya tanpa satu pun pengambil bertipe. Arah sebaliknya dilayani makro %* yang menerima objek apa pun, sehingga dokumen dan objek saling mengisi tanpa salin-tempel bidang. Dokumen yang rusak dikenali saat penguraian, karena parseJson melemparkan JsonParsingError yang menyebut posisi kesalahannya, dan blok try di sekitar penguraian menjadi tempat yang tepat untuk pesan kesalahan yang ramah bagi pemakai.
Penulisan tanpa notasi %* juga tersedia untuk pembangunan bertahap, yaitu newJObject menciptakan objek kosong dan newJArray menciptakan larik kosong, lalu keduanya diisi dengan add dan penugasan indeks. Cara ini cocok ketika struktur dokumen baru diketahui di tengah perulangan, misalnya satu entri per baris berkas sumber, dan hasil akhirnya tetap JsonNode yang dapat dicetak, diuraikan ulang, atau ditulis ke berkas.
Serialisasi objek dengan marshal#
Modul marshal bekerja pada tingkat yang berbeda, yaitu objek Nim yang dinyatakan dengan type. Operator $$ mengubah nilai apa pun yang tersusun atas tipe standar menjadi representasi teks yang juga berbentuk JSON, sedangkan to[T] menguraikannya kembali menjadi objek bertipe tanpa penulisan pengambil bidang satu per satu. Tipe dan bentuk data diperiksa pada saat penguraian, sehingga kesalahan bentuk terdeteksi lebih dini.
# arsip_marshal.nim: serialisasi objek Nim dengan modul marshal
import marshal
type NilaiUjian = object
nama: string
skor: int
let data = @[
NilaiUjian(nama: "Ali", skor: 88),
NilaiUjian(nama: "Citra", skor: 91),
]
let teks = $$data
echo teks
let bacaan = to[seq[NilaiUjian]](teks)
for n in bacaan:
echo n.nama, ": ", n.skor# kompilasi dan jalankan program arsip marshal
nim c --hints:off -r arsip_marshal.nim[{"nama": "Ali", "skor": 88}, {"nama": "Citra", "skor": 91}]
Ali: 88
Citra: 91Bentuk teks hasil $$ padat tanpa spasi karena ditujukan bagi mesin, sedangkan $ menghasilkan representasi satu baris dan pretty menambah indentasi. Ketiganya berbagi satu pengurai yang sama, sehingga arsip yang ditulis dengan salah satu tetap terbaca oleh to[T] tanpa penyetelan.
Perbandingan keduanya menegaskan pembagian tugasnya. Modul json menuntut dokumen dibangun bidang demi bidang dengan %* dan dibaca dengan pengambil bertipe, tetapi sebagai imbalannya menerima JSON dari pihak mana pun, termasuk layanan web dan berkas konfigurasi milik perangkat lunak lain. Modul marshal hampir tanpa upaya karena objek langsung berubah menjadi teks, namun format hasilnya ditujukan untuk program Nim, sehingga tidak dijanjikan sebagai antarmuka untuk bahasa lain. Pembagian ini membuat keputusan bentuk data berpindah ke saat desain, yaitu format bersama dipikirkan matang di awal, sedangkan arsip internal dibiarkan mengikuti tipe program, dan keduanya tidak perlu saling menunggu.
Kesalahan umum#
- Menganggap hasil
parseJsonbertipe data langsung. Nilaibacaan["sensor"]tetapJsonNode, sehinggaecho bacaan["sensor"]mencetak representasi JSON-nya, bukan isi lariknya, dan penelusuran denganforbaru menghasilkan elemen per elemen. - Memanggil pengambil bertipe yang tidak cocok, misalnya
getStrpada node angka. Program berhenti dengan error yang menyatakan ketidakcocokan tipe pada posisi pemanggilan, dan cara amannya memeriksakindterlebih dahulu bila bentuk dokumen belum pasti. - Menggunakan
marshalsebagai format pertukaran dengan pihak lain. Representasi$$berikatan dengan tipe Nim, sehingga perubahan kecil padatypemengubah teksnya, dan pemakai luar yang mengandalkan bentuk itu akan rusak tanpa peringatan.
Ringkasan#
- Modul
jsonmewakili dokumen sebagaiJsonNode, dibangun dengan%*, ditulis denganpretty, dibaca denganparseJson, dan ditelusuri dengan indeks disertai pengambil bertipe sepertigetStrdangetFloat. - Modul
marshalmengubah objek Nim menjadi teks dengan$$dan menguraikannya kembali denganto[T], sehingga arsip objek tidak memerlukan penulisan bidang satu per satu. - Pilihan modul mengikuti mitra data, yaitu
jsonuntuk format lintas bahasa yang disepakati bersama, danmarshaluntuk kebutuhan internal program Nim.
Referensi#
- Module json — Nim documentation
— Kontrak
%*,parseJson,pretty, dan pengambil bertipe padaJsonNode. - Module marshal — Nim documentation
— Operator
$$dan proctobeserta batasan formatnya. - Nim Tutorial Part 1 — Nim documentation — Pengantar modul pustaka standar pada tutorial resmi Nim.