JSON Bandingkan
Bandingkan dua objek JSON dan lihat perbedaan yang disorot.
Tentang perbandingan JSON
Perbandingan JSON (juga disebut diff JSON) mengidentifikasi perbedaan antara dua struktur JSON. Tidak seperti diff teks polos, perbandingan yang memahami JSON tahu kunci dan nilai, sehingga dapat memberi tahu Anda persis properti mana yang ditambahkan, dihapus, atau dimodifikasi · terlepas dari urutan kunci.
Alat ini melakukan perbandingan mendalam dan rekursif dari dua objek JSON. Ia menangani objek bersarang, array, string, angka, boolean, dan nilai null. Semua pemrosesan dilakukan secara lokal di browser Anda.
Sejarah Singkat JSON
Biografi JSON lebih pendek dari bahasa pemrograman rata-rata dan jauh kurang dramatis. Akronim berasal dari State Software, Inc., sebuah perusahaan kecil yang didirikan Douglas Crockford dan Chip Morningstar pada Maret 2001 untuk membangun apa yang kemudian disebut aplikasi web Ajax. Pesan JSON pertama dikirim pada April 2001, dari komputer di garasi Bay-Area Morningstar. Crockford tidak mengklaim telah menemukan JSON, dia mengupasnya dari sintaks literal objek JavaScript, memberinya nama, dan membuat situs web. Dia mengakuisisi json.org pada 2002 dan memposting tata bahasa diagram-rel di sana. Selama empat tahun JSON menyebar dari mulut ke mulut dan tetesan lambat implementasi pustaka. Pada Desember 2005, Yahoo! mulai menawarkan beberapa layanan webnya dalam JSON, momen yang ditunjukkan kebanyakan sejarawan sebagai JSON menyeberang ke arus utama. Standardisasi datang dalam gelombang: RFC 4627 (Juli 2006), ditulis oleh Crockford sendiri, dengan status informatif daripada standards-track; edisi pertama ECMA-404 (Oktober 2013); RFC 7159 (Maret 2014), yang menempatkan JSON di IETF Standards Track dan melonggarkan persyaratan bahwa nilai tingkat atas harus berupa objek atau array. Versi saat ini adalah RFC 8259 (Desember 2017), sekarang Internet Standard STD 90, dan edisi kedua ECMA-404 (Desember 2017). Keduanya sengaja identik dalam tata bahasa; teks IETF menambahkan panduan keamanan dan interoperabilitas yang sengaja dihilangkan oleh teks Ecma.
Dua Keluarga Algoritma: Diff Baris dan Diff Struktural
Ilmu komputer telah memikirkan tentang diffing sejak tahun 1970-an. Douglas McIlroy (McIlroy yang sama yang menemukan pipe Unix) dan James W. Hunt menulis Unix diff asli pada awal 1970-an; itu dikirim sebagai bagian dari Edisi ke-5 Unix pada 1974, dengan algoritma yang mendasari didokumentasikan di Bell Labs Computing Science Technical Report #41 pada Juni 1976. Hunt-McIlroy dibangun di atas masalah subsequence umum terpanjang, temukan urutan terpanjang dari baris yang muncul berurutan di kedua input, dan segala sesuatu yang tidak ada dalam urutan itu adalah baik penghapusan atau penyisipan. Satu dekade kemudian, Eugene W. Myers menerbitkan "An O(ND) Difference Algorithm and Its Variations" di Algorithmica Vol 1, Issue 2 (1986), membingkai ulang masalah sebagai pencarian jalur terpendek atas "edit graph", dasar untuk implementasi Unix diff yang lebih cepat yang berjalan dua hingga empat kali lebih cepat dari pendahulunya. Hari ini, git diff default ke algoritma histogram di LibXDiff, umumnya lebih cepat dari Myers vanilla dan menghasilkan output yang lebih mudah dibaca, terutama di sekitar blok yang dipindahkan. Patience diff (Bram Cohen, 2008) adalah penghalusan LCS lain yang memprioritaskan baris jangkar unik. Semua variasi pada tema: LCS baris demi baris, memperlakukan input sebagai urutan datar token opak. Tidak satu pun dari mereka yang tahu apa itu JSON.
Keluarga diff struktural mengambil pendekatan berbeda: berjalan kedua input secara paralel, membandingkan primitif dengan kesetaraan ketat, menghitung union dari kunci objek (hadir-di-kiri saja adalah "dihapus", hadir-di-kanan saja adalah "ditambahkan", hadir-di-keduanya berarti recurse), dan berjalan array berdasarkan indeks. Untuk setiap posisi, recurse. Jika satu array lebih panjang, elemen ekstra ditambahkan atau dihapus. Perubahan tipe (angka vs string, objek vs array) menjadi entri "type changed". Ini adalah algoritma yang jsondiffpatch implementasikan sebagai kasus dasarnya, dan ini adalah algoritma yang diimplementasikan alat ini. Kekuatannya adalah outputnya bermakna: setiap perubahan yang dilaporkan memiliki jalur di dalam dokumen (user.address.city, items[3].price) dan semantik yang jelas. Kelemahannya adalah langkah ketiga, perbandingan array berdasarkan indeks, yang menghasilkan omong kosong setiap kali sebuah elemen dimasukkan di dekat depan array panjang.
Masalah Tersulit dalam JSON Diffing: Array
Misalkan JSON "before" Anda berisi array ["alpha", "beta", "gamma", "delta"] dan JSON "after" Anda berisi ["alpha", "new", "beta", "gamma", "delta"]. Diff berbasis indeks naif melaporkan empat perubahan: indeks 1 berubah dari "beta" menjadi "new"; indeks 2 berubah dari "gamma" menjadi "beta"; indeks 3 berubah dari "delta" menjadi "gamma"; indeks 4 menambahkan "delta". Manusia yang melihat ini akan mengatakan ada satu perubahan: penyisipan tunggal di indeks 1. Ini adalah masalah LCS yang sama yang diselesaikan keluarga line-diff di tahun 1970-an, diterapkan pada array nilai JSON daripada array baris teks. jsondiffpatch melakukan persis itu, menghitung LCS dari dua array dan mengeluarkan penyisipan dan penghapusan relatif terhadapnya. Untuk array primitif ini bekerja dengan baik. Untuk array objek tidak: [{id: 1, name: "Alice"}] versus [{id: 1, name: "Alicia"}] tidak memiliki subsequence umum dengan kesetaraan referensi, jadi LCS naif melaporkan "hapus seluruh elemen kiri, tambahkan seluruh elemen kanan" padahal kebenarannya adalah satu field dari satu elemen yang berubah. Solusi jsondiffpatch adalah callback objectHash: pemanggil menyediakan fungsi yang memetakan setiap objek ke kunci identitas (biasanya obj => obj.id), dan diff mencocokkan elemen array berdasarkan identitas daripada referensi. Ini adalah masalah umum yang sulit yang belum dipecahkan sepenuhnya oleh siapa pun. Alat Absolutool, sesuai FAQ-nya sendiri, membandingkan array berdasarkan indeks, tidak mengimplementasikan LCS atau objectHash. Itu adalah pilihan ruang lingkup yang disengaja untuk alat gratis kecil: sangat baik pada diff objek dan lebih lemah pada array di mana elemen telah dimasukkan atau diurutkan ulang.
JSON Patch (RFC 6902): Diff sebagai Format Transport
RFC 6902, "JavaScript Object Notation (JSON) Patch," diterbitkan pada April 2013. Ini mendefinisikan tipe media application/json-patch+json dan bahasa patch enam operasi: add, remove, replace, move, copy, test. Patch itu sendiri adalah dokumen JSON, array dari objek operasi, masing-masing dengan kunci op, kunci path (JSON Pointer ke lokasi target), dan nilai atau field from sesuai kebutuhan. Operasi diterapkan dalam urutan, secara atomik: jika salah satu gagal, seluruh patch ditolak. Sintaks jalur berasal dari RFC 6901, "JSON Pointer," dokumen pendamping yang diterbitkan pada bulan yang sama, sintaks string kecil dari token referensi yang dipisahkan slash (/user/address/city berarti "nilai pada kunci city di dalam address di dalam user"; /items/3 berarti "elemen keempat dari items", terindeks nol). Karena / dan ~ spesial, mereka di-escape ke ~1 dan ~0 masing-masing (dalam urutan itu, dekode ~1 terlebih dahulu untuk menghindari bug dekode ganda). JSON Patch adalah format output yang tepat untuk alat diff JSON yang ingin memberi makan hasilnya ke mesin lain. Metode HTTP PATCH (RFC 5789) dirancang untuk jenis payload pembaruan parsial seperti ini. Kubernetes mendukung RFC 6902 bersama dengan format strategic-merge-patch-nya sendiri. Alat ini saat ini tidak mengeluarkan JSON Patch, itu adalah arah fitur masa depan, bukan saat ini.
JSON Merge Patch (RFC 7396): Alternatif yang Lebih Sederhana dan Lossy
RFC 7396, "JSON Merge Patch," diterbitkan pada Oktober 2014 oleh Paul Hoffman dan James Snell. Tidak menggunakan operasi sama sekali, dokumen patch hanyalah objek JSON parsial yang menutupi yang asli. Field manapun yang hadir di patch menimpa field yang sesuai di asli; field manapun yang diatur ke null di patch menghapus field itu; field manapun yang absen dari patch dibiarkan tidak berubah; array diganti sepenuhnya, tidak pernah digabungkan. Merge Patch ringkas dan mudah ditulis dengan tangan. Trade-off adalah hilangnya ekspresivitas: tidak ada cara untuk mengatur nilai field ke literal null (karena null berarti "hapus"); tidak ada cara untuk memodifikasi satu elemen array (seluruh array diganti); tidak ada cara untuk mengekspresikan pemindahan atau salinan; tidak ada cara untuk membedakan "saya tidak menyentuh field ini" dari "saya ingin mengaturnya ke nilai saat ini". Untuk sebagian besar pembaruan API sehari-hari, batasan ini dapat diterima, itulah sebabnya Merge Patch adalah yang lebih populer dari dua format. RFC 6902 menang dalam skenario di mana salah satu batasan menggigit. Kubernetes menggunakan kedua format secara sengaja, memilih yang tepat untuk setiap konteks.
Bagaimana Diff Visual Dirender
Ada tiga konvensi visual umum untuk menampilkan diff struktural. Side-by-side, dua kolom, asli di kiri, dimodifikasi di kanan, dengan baris yang sesuai dijajarkan (layout yang digunakan alat ini untuk inputnya). Diff terpadu inline, kolom tunggal menampilkan baris yang dihapus (biasanya dengan prefiks - dan diwarnai merah), baris yang ditambahkan (+, hijau), dan baris konteks yang tidak berubah (tanpa prefiks, teks biasa), layout yang git diff gunakan secara default. Tampilan pohon, render JSON sebagai pohon yang dapat diciutkan, dengan node yang berubah disorot dan node yang tidak berubah dilipat. Konvensi warna sangat konsisten di seluruh ekosistem: hijau untuk penambahan, merah untuk penghapusan, kuning atau amber untuk nilai yang berubah, abu-abu netral untuk tidak berubah. Alat ini mengikuti konvensi secara tepat: hijau muda untuk penambahan, merah muda untuk penghapusan, kuning muda untuk perubahan. Sebagian besar pengguna akan mengenali warna dari GitHub, GitLab, BitBucket, setiap tampilan diff IDE dan puluhan alat online.
Penggunaan umum
- Bandingkan respons API sebelum dan sesudah perubahan kode
- Temukan perbedaan antara file konfigurasi
- Meninjau lockfile yang dihasilkan.
package-lock.json,yarn.lock,poetry.lock,Cargo.lockdanterraform.tfstatesemuanya adalah file JSON-atau-berdekatan-JSON yang dihasilkan mesin yang berubah dengan cara berisik selama pengembangan normal. Diff yang sadar-JSON jauh lebih berguna daripada diff teks untuk memahami apa yang sebenarnya bergerak. - Memverifikasi round-trip serialisasi. Serialisasi baris database ke JSON, lewatkan melalui jaringan, deserialisasi, re-serialisasi. Apakah ada yang berubah? Diff menangkap bug diam di serializer khusus, terutama seputar tanggal, presisi numerik, dan penanganan null.
- Pengujian regresi output JSON. Snapshot output JSON yang diketahui baik; diff setiap run berikutnya terhadap snapshot dan gagalkan tes jika ada yang berubah.
- Membandingkan draft skema. Dokumen JSON Schema dan OpenAPI sendiri adalah JSON. Diff dua versi skema mengungkapkan dengan tepat field mana yang menjadi wajib, opsional atau memiliki tipe yang dipertegas.
- Verifikasi keakuratan migrasi data
Kasus Tepi yang Perlu Diketahui
Presisi angka. RFC 8259 mengatakan angka JSON adalah presisi-sembarang dan tidak menetapkan batas atas pada berapa banyak digit yang dapat dimiliki angka. JavaScript, bagaimanapun, mem-parse setiap angka sebagai IEEE 754 double 64-bit. Di atas Number.MAX_SAFE_INTEGER (253 − 1 = 9.007.199.254.740.991), bilangan bulat mungkin diam-diam kehilangan presisi saat di-round-trip melalui diff berbasis JavaScript. Masalah yang sama mempengaruhi floating-point, 0.1 + 0.2 terkenal tidak persis 0.3 di IEEE 754. JSON ketat juga melarang koma trailing dan komentar; keduanya adalah kesalahan sintaks per RFC 8259. JSON5 (json5.org) adalah superset formal yang memungkinkan komentar, koma trailing, kutipan tunggal, kunci tanpa kutipan, angka hex, titik desimal awal/trailing, dan Infinity/NaN. JSONC adalah mode "JSON dengan Komentar" Microsoft yang digunakan dalam file pengaturan VS Code. Alat ini menggunakan JSON.parse() dan akan menolak keduanya, lepaskan komentar dan koma trailing sebelum menempel.
String tanggal. JSON tidak memiliki tipe tanggal native. Tanggal biasanya dikodekan sebagai string, dengan standar de-facto adalah ISO 8601 (dan secara khusus profil RFC 3339 yang digunakan kebanyakan API internet): YYYY-MM-DDTHH:MM:SS[.fff]Z. Diff yang membandingkan tanggal sebagai string akan melaporkan 2024-01-01T00:00:00Z dan 2024-01-01T00:00:00.000Z sebagai berbeda, meskipun mereka mewakili instan yang sama, karena string berbeda. Kunci duplikat. RFC 8259 §4 menyatakan "nama dalam objek SEHARUSNYA unik", SHOULD secara normatif lebih lemah dari MUST. JSON.parse() JavaScript menerima kunci duplikat dan secara diam-diam menjaga yang terakhir; parser lain mungkin menjaga yang pertama atau memunculkan kesalahan. null vs hilang. {"a": null} dan {} adalah nilai JSON yang berbeda. Alat ini melaporkan yang pertama sebagai "kunci a memiliki nilai null" dan yang kedua sebagai "tidak ada kunci a", mereka dibedakan dengan benar. Perlakuan JSON Merge Patch terhadap null sebagai sinyal hapus adalah pengakuan tingkat format bahwa perbedaan itu nyata dan rumit.
Ekosistem di 2026
Diff JSON open-source didominasi oleh segelintir pustaka. jsondiffpatch oleh Benjamin Eidelman, pertama kali diterbitkan pada 2012, adalah pustaka JavaScript de-facto: ~5k bintang GitHub, mendukung objectHash, array LCS, patch terbalik dan formatter HTML visual. json-diff oleh Andrey Tarantsov adalah alat Node CLI kanonik, dengan nama yang sama dibagi oleh implementasi paralel di Python, Go dan Rust. DeepDiff oleh Sep Dehpour adalah pustaka Python dominan, diff rekursif dengan opsi untuk mengabaikan urutan, mengabaikan perubahan tipe numerik, dan banyak kontrol halus. Diffing JsonNode Linux Foundation di Jackson (Java) adalah pilihan JVM standar. jq tidak memiliki perintah diff native tetapi keluarga operator = dan //-nya dapat mengekspresikan perbandingan struktural sederhana. Diff bawaan VS Code menangani JSON melalui mode teks; ekstensi JSON Tools menambahkan perbandingan sadar-JSON. Alat online seperti Diffchecker menawarkan mode JSON yang pada dasarnya adalah walk rekursif yang sama yang diimplementasikan alat ini, sering dilapisi di atas pustaka yang sama.
Mengapa Browser-Saja Penting di Sini
Diffing dua payload JSON di server membutuhkan mengunggah keduanya. Untuk contoh data publik biasa ini tidak berbahaya. Untuk respons API yang berisi token autentikasi, PII pelanggan, catatan karyawan internal, rahasia konfigurasi, atau data produk yang belum dirilis, tidak. Bahkan setelah diff selesai, payload tersebut tetap berada di log server, mungkin di cache CDN, mungkin di pipeline analitik, mungkin di backup. Diff hanya-browser tidak pernah mentransmisikan, JSON di-parse dan di-walk sepenuhnya di tab Anda. Anda dapat memverifikasi dengan membuka tab Network DevTools saat Anda mengklik Compare; tidak ada permintaan keluar. Untuk membandingkan respons API terhadap baseline, debug drift konfigurasi antara lingkungan, atau audit perubahan dalam lockfile yang berisi URL paket internal, "JSON tidak pernah meninggalkan perangkat saya" adalah arsitektur yang membuat alat aman digunakan pada data produksi nyata.
Pertanyaan umum
Apakah urutan kunci memengaruhi perbandingan?
Tidak. Objek JSON tidak terurut menurut spesifikasi, jadi {"a":1, "b":2} dan {"b":2, "a":1} diperlakukan sebagai identik. Hanya perbedaan nilai yang sebenarnya yang dilaporkan.
Bagaimana array dibandingkan?
Array dibandingkan berdasarkan indeks. Jika array pada indeks 2 berbeda antara kedua input, indeks tertentu itu ditandai. Elemen yang ditambahkan atau dihapus di akhir array juga dideteksi.
Apa yang terjadi dengan objek yang sangat bersarang?
Perbandingan sepenuhnya rekursif. Objek dan array yang bersarang pada kedalaman berapa pun dibandingkan properti demi properti. Output menampilkan jalur lengkap dari setiap perbedaan (mis. «user.address.city»).
Mengapa perbandingan bilangan bulat besar saya terlihat salah?
JavaScript mem-parse setiap angka JSON sebagai IEEE 754 double 64-bit. Di atas Number.MAX_SAFE_INTEGER (253 − 1 = 9.007.199.254.740.991), bilangan bulat mungkin diam-diam kehilangan presisi. Jadi file JSON yang berisi 9007199254740993 mungkin dibandingkan identik dengan file yang berisi 9007199254740992. Ini adalah batasan dari representasi angka yang mendasari, bukan alat diff. Jika Anda mendiff data yang berisi ID 64-bit (ID snowflake Twitter, ID Discord, kunci database besar), suruh serializer Anda mengeluarkannya sebagai string daripada angka. Perbandingan floating-point memiliki peringatan yang sama: 0.1 + 0.2 terkenal tidak persis 0.3 di IEEE 754.
Bisakah saya membandingkan JSON5 atau JSONC (JSON dengan komentar)?
Tidak secara langsung. Alat ini menggunakan JSON.parse() bawaan browser, yang mengikuti RFC 8259 dengan ketat, komentar, koma trailing, string yang dikutip tunggal, dan kunci tanpa kutipan adalah kesalahan sintaks. Jika input Anda adalah JSON5 (json5.org) atau JSONC gaya VS Code, lepaskan komentar dan koma trailing terlebih dahulu, atau jalankan melalui alat seperti jsonc-parser untuk dikonversi ke JSON ketat sebelum menempel.
Apakah JSON saya dikirim ke server?
Tidak. Perbandingan berjalan sepenuhnya di browser Anda melalui JavaScript. JSON yang ditempel tidak pernah melintasi jaringan, verifikasi di tab Network DevTools saat Anda mengklik Compare, atau bawa halaman offline setelah dimuat dan konfirmasi diff masih bekerja. Aman untuk membandingkan respons API dengan token autentikasi, file konfigurasi dengan rahasia, atau ekspor database yang berisi PII pelanggan.