38 poin oleh GN⁺ 2025-12-05 | 10 komentar | Bagikan ke WhatsApp
  • JSON, yang telah menjadi standar untuk web API, mudah dibaca dan fleksibel, tetapi memiliki keterbatasan dalam hal performa dan stabilitas
  • Protobuf (Protocol Buffers) menjamin struktur data secara jelas melalui definisi tipe yang ketat dan pembuatan kode otomatis
  • Dengan menggunakan serialisasi biner, Protobuf dapat mengurangi ukuran data lebih dari sekitar 3x dan meningkatkan kecepatan transmisi dibanding JSON
  • Server dan klien berbagi skema .proto yang sama sehingga tidak ada ketidakcocokan tipe atau kebutuhan validasi manual
  • Walau lebih sulit untuk di-debug, Protobuf lebih cocok untuk API modern dari sisi performa, maintainability, dan efisiensi pengembangan

Universalitas dan Keterbatasan JSON

  • JSON adalah format teks yang mudah dibaca manusia, sehingga data bisa diperiksa hanya dengan console.log() sederhana
  • Berkat integrasi sempurna dengan web, JSON diadopsi luas di JavaScript dan berbagai framework backend
  • JSON menawarkan fleksibilitas untuk menambah, menghapus, atau mengubah tipe field dengan bebas, tetapi hal ini juga membuka kemungkinan ketidakcocokan struktur dan error
  • Karena ekosistem tooling-nya kaya, JSON bisa ditangani dengan mudah hanya menggunakan editor teks atau curl
  • Namun, terlepas dari keunggulan tersebut, ada alternatif yang lebih baik dalam hal performa dan type safety

Gambaran Umum Protobuf

  • Format serialisasi biner yang dikembangkan oleh Google pada 2001 dan dipublikasikan pada 2008
  • Digunakan secara luas di sistem internal dan komunikasi antar-microservice
  • Sering ada kesalahpahaman bahwa Protobuf harus dipakai bersama gRPC, padahal Protobuf juga bisa digunakan secara mandiri di HTTP API
  • Pada awalnya kurang mudah diakses karena format biner tidak terlihat langsung, tetapi Protobuf sangat unggul dari sisi efisiensi dan stabilitas

Sistem Tipe yang Kuat dan Pembuatan Kode

  • Protobuf mendefinisikan struktur data secara jelas melalui file .proto
    • Setiap field memiliki tipe ketat, identifier numerik, dan nama tetap
  • Contoh:
    message User {
      int32 id = 1;
      string name = 2;
      string email = 3;
      bool isActive = 4;
    }
    
    Iklan
  • Dengan perintah protoc, Protobuf mendukung pembuatan kode otomatis untuk banyak bahasa seperti Dart, TypeScript, Kotlin, Swift, C#, Go, dan Rust
  • Kode yang dihasilkan digunakan untuk serialisasi (writeToBuffer) dan deserialisasi (fromBuffer), sehingga validasi atau parsing manual tidak diperlukan
  • Hasilnya, menghemat waktu sekaligus meningkatkan maintainability

Efisiensi Serialisasi Biner

  • Protobuf diserialisasi sebagai data biner alih-alih teks, sehingga sangat ringkas dan cepat
  • Perbandingan ukuran untuk data yang sama (objek User):
    • JSON: 86 byte (68 byte jika spasi dihapus)
    • Protobuf: 30 byte
  • Penyebab efisiensinya:
    • Menggunakan encoding varint untuk angka
    • Menggunakan tag numerik, bukan key teks
    • Menghapus spasi dan sintaks yang tidak perlu
    • Optimasi field opsional
  • Hasilnya adalah penghematan bandwidth, respon lebih cepat, hemat data seluler, dan peningkatan pengalaman pengguna

Contoh API Protobuf Berbasis Dart

  • Menggunakan paket shelf untuk membuat HTTP server sederhana yang mengembalikan objek User dalam format Protobuf
  • Inti kode server:
    • Membuat objek User() lalu menserialisasikannya dengan writeToBuffer()
    • Menetapkan header respons 'content-type': 'application/protobuf'
  • Klien menggunakan paket http dan user.pb.dart untuk mendekode data Protobuf secara langsung
  • Karena server dan klien berbagi skema .proto yang sama, ketidakcocokan struktur data tidak terjadi
  • Pendekatan yang sama juga dapat diterapkan di Go, Rust, Kotlin, Swift, C#, dan TypeScript
Iklan

Keunggulan JSON yang Masih Tersisa

  • Protobuf sulit dipahami maknanya tanpa skema
    • Karena yang terlihat hanya identifier angka, bukan nama field, format ini sulit dibaca manusia
  • Contoh perbandingan:
    • JSON: { "id": 42, "name": "Alice" }
    • Protobuf: 1: 42, 2: "Alice"
  • Karena itu, Protobuf memerlukan:
    • tool decoding khusus
    • manajemen skema dan versioning yang wajib
  • Meski begitu, keuntungan performa dan efisiensinya jauh lebih besar

Kesimpulan

  • Protobuf adalah teknologi serialisasi yang matang dan berperforma tinggi, serta cukup layak digunakan juga untuk API publik
  • Dapat berjalan mandiri di HTTP API biasa tanpa gRPC
  • Alat yang meningkatkan performa, robustness, pengurangan error, dan efisiensi pengembangan sekaligus
  • Untuk proyek generasi berikutnya, mengadopsi Protobuf sangat layak dipertimbangkan

10 komentar

 
tested 2025-12-09
 
onixboox 2025-12-08

https://msgpack.org/ bagaimana dengan yang ini?

 
cosine20 2025-12-08

MessagePack juga bagus.

 
savvykang 2025-12-06

Saya rasa kontradiktif untuk mengklaim format yang bahkan tidak memiliki decoder resmi untuk debugging sebagai sesuatu yang matang.

 
jjw9512151 2025-12-05

Seperti semua alat lainnya, tidak ada yang serba bisa, tetapi saya rasa Protobuf juga merupakan alat yang cukup baik.
Khususnya ketika pernah ada kebutuhan untuk mengirimkan data berkapasitas besar dan berfrekuensi tinggi (20 kali per detik) ke berbagai bahasa [klien] di lingkungan embedded, saya pernah menanganinya dengan rapi menggunakan nanopb.

 
ifmkl 2025-12-05

Kalau dibuat seketat itu, bukannya malah jadi pakai XML ya? haha

 
click 2025-12-06

Skema juga bisa didefinisikan dengan DTD, dan jika di sisi parser di-cache, efeknya skema hanya perlu dikirim sekali.

 
bakyeono 2025-12-05
  • Format biner yang saya impikan berbasis skema, tetapi juga menyertakan skema di dalam pesan. Dengan begitu, format itu bisa langsung dibaca lewat plugin vim. Saat menangani jutaan objek, menempelkan skema 1KB ke pesan 2GB bukanlah beban besar
  • Namun pada layanan web, justru sering ada kasus skemanya 200KB sementara pesannya 1KB. Dalam situasi seperti ini, itu jadi tidak efisien

=> Bukankah bagaimanapun juga skema memang harus dikirim setidaknya sekali? Bahkan pada JSON pun bukan berarti tidak ada skema; skemanya hanya tersirat dan ikut terkandung di dalam data, jadi rasanya bukan berarti skema tidak dikirim. Malah, karena skema yang sama dikirim berulang pada setiap item, itu justru lebih tidak efisien. "Berbasis skema tetapi juga menyertakan skema di dalam pesan" terdengar seperti ide yang cukup bagus.

 
GN⁺ 2025-12-05
Komentar Hacker News
  • JSON sering kali membuat kita mengirim data yang ambigu atau tidak terjamin. Berbagai masalah bisa muncul, seperti field yang hilang, kesalahan tipe, typo pada key, atau struktur yang tidak terdokumentasi. Ada tulisan yang berargumen bahwa Protobuf membuat hal-hal ini mustahil terjadi dengan mendefinisikan struktur pesan secara jelas lewat file .proto. Namun ini adalah salah paham terhadap filosofi Protobuf. Di proto3, field required memang tidak didukung. Dokumentasi resmi (Protobuf Best Practices) juga secara eksplisit menyatakan bahwa “required fields are harmful and were removed”. Pada akhirnya, klien Protobuf juga harus ditulis secara defensif seperti API JSON

    • Blog tersebut punya banyak salah paham serupa. Misalnya, dalam tulisan yang menentang penggunaan SVG, ia tidak mempertimbangkan keunggulan skalabilitas bebas dari format vektor
    • Inti masalahnya hanyalah perbedaan bahasa atau implementasi klien/server. Saya memakai framework Gooey di sisi klien dengan memanfaatkan konsep Marshalling di Go. Jika keterbatasan Go bisa diatasi, ini bisa dipakai dengan sangat type-safe. Namun, penting untuk memblokir field private dengan json:"-". Proyek saya bisa dilihat di Gooey
    • Tulisan ini mencampuradukkan konsep format serialisasi dan kontrak (Contract)
    • Dalam sistem jaringan, masalah ketidakcocokan data (skew) selalu ada terlepas dari cara encoding-nya. Bedanya, Protobuf menyediakan objek bertipe statis setelah decoding. JSON juga bisa divalidasi, tetapi kebanyakan orang tidak melakukannya. Akibatnya, objek JSON dimodifikasi ke sana kemari hingga tak ada yang benar-benar yakin dengan strukturnya
    • Mungkin penulis aslinya hanya ingin mengatakan bahwa di Protobuf field yang hilang diinisialisasi dengan nilai default. Ini berbeda dari konsep field “required”
  • JSON yang dikompresi sudah cukup layak dipakai, dan biaya komunikasi awalnya rendah. Tentu akan jadi masalah jika ada field yang hilang atau tipe berubah, tetapi kebanyakan orang yang mencoba merancang struktur yang sepenuhnya typed dan membuat proses sinkronisasi versi biasanya gagal. Pada akhirnya, opsi dengan biaya manusia yang lebih rendah akan menang. Karena itu, JSON tidak akan hilang sampai ada pengganti dengan biaya komunikasi antarmanusia yang lebih rendah

    • Betul. Kebanyakan arsitek bahkan tidak mempertimbangkan proto kecuali ada kebutuhan jelas seperti gRPC. JSON tidak akan tergantikan sampai ada alternatif yang bisa langsung di-debug dengan console.log()
    • Debugging juga merupakan kekuatan JSON. Tinggal dibuka dan dibaca. Sebaliknya, Protobuf memerlukan tooling
    • Benar. Namun orang-orang cenderung memilih tidak menginvestasikan 15 menit tambahan saat tahap desain, lalu malah menghabiskan 3 bulan menelusuri ulang masalah di kemudian hari
    • JSON mungkin tidak akan benar-benar hilang seperti COBOL, tetapi untuk proyek baru, tidak ada alasan kuat untuk memakainya
  • Protobuf tidak sempurna. Jika server dan klien dirilis pada waktu berbeda sehingga versi spesifikasinya berbeda, jaminan keamanannya runtuh. Ini bisa dikurangi dengan larangan reuse ID, penyalinan unknown-field, dan sebagainya, tetapi sistem terdistribusi pada dasarnya memang kompleks. Meski begitu, protobuf3 telah menyelesaikan banyak masalah di protobuf2. Dulu kita tidak bisa membedakan apakah nilai default memang disetel atau field-nya hilang, tetapi sekarang ini bisa diatasi dengan memakai tipe message

    • Baik JSON maupun Protobuf hanya aman jika uji kompatibilitas versi dipaksakan di pipeline CI
    • Sistem tipe apa pun akan rusak saat melewati jaringan
  • Dalam tulisan itu disebut “super efisien”, tetapi tidak ada pembahasan tentang gzip. Kebanyakan data teks sekarang sudah ditransmisikan dalam keadaan terkompresi secara otomatis. Karena itu, Protobuf seharusnya dibandingkan dengan JSON yang sudah digzip

    • Saya juga pernah menguji berbagai format biner, tetapi pada akhirnya JSON yang digzip jauh lebih efisien
    • Kekurangan JSON adalah kecepatan serialisasi/deserialisasi. Selebihnya bisa diperbaiki secara bertahap
    • Streaming Brotli/zstd JSON/HTML juga layak dipertimbangkan. Saat koneksi dipertahankan, jendela kompresi bisa dimanfaatkan
    • Referensi terkait: artikel perbandingan performa Protobuf dari Auth0
    • Kombinasi JSON dan mod_deflate memberi perbedaan yang sangat terasa
  • Tidak masalah mendukung protokol yang lebih baik, tetapi sulit mengatakan bahwa Protobuf menggantikan JSON baik dalam efisiensi maupun kegunaan. Protobuf justru kehilangan area yang dikuasai JSON karena skemanya ketat. Sebaliknya, CBOR lebih cocok sebagai pengganti JSON. CBOR tetap fleksibel seperti JSON, tetapi memakai encoding yang lebih ringkas

    • Namun skema ketat di Protobuf justru bisa menjadi kelebihan. Kebanyakan API tidak pernah mempublikasikan skema JSON. Saya pernah memvalidasi dengan ajv atau superstruct, tetapi dengan Protobuf itu tidak diperlukan
    • Akan bagus jika browser mendukung API CBOR secara langsung. Implementasi internalnya sudah ada, jadi seharusnya tidak sulit
  • ASN.1 dari tahun 1984 sebenarnya sudah melakukan apa yang dilakukan Protobuf, tetapi dengan lebih fleksibel. Jika memakai encoding DER, hasilnya juga tidak buruk. Lihat saja contoh ASN.1 DER. Protobuf terlalu kompleks dibanding apa yang berhasil dicapainya

    • ASN.1 punya terlalu banyak fitur. Jika semuanya didukung, library-nya jadi terlalu kompleks, tetapi jika hanya sebagian yang didukung, itu tidak lagi menjadi ASN.1 standar
    • Saya lebih suka ASN.1 DER. Saya pernah merilis encoder/decoder DER yang saya implementasikan sendiri dalam C sebagai FOSS. Saya juga membuat ekstensi “ASN.1X” yang sepenuhnya mencakup model data JSON
    • Namun dalam sistem seperti SNMP, fleksibilitas berlebihan pada ASN.1 justru menjadi masalah. Setiap vendor memperluasnya sesuka hati
    • Bahkan di internal Google, serialisasi/deserialisasi Protobuf menghabiskan banyak CPU
    • ASN.1 itu overengineered sehingga sulit didukung. Fitur seperti inheritance tidak diperlukan
  • Saya pernah membangun seluruh sistem produksi dengan Protobuf, dan pengelolaannya sendiri sangat menyakitkan. Secara teknis terlihat bagus, tetapi dalam praktiknya JSON jauh lebih sederhana

    • Keterbacaan dan kemudahan debugging JSON tidak bisa diremehkan. Kebanyakan tim memilih JSON demi efisiensi jangka pendek
    • Saya penasaran masalah apa yang Anda alami. Dalam pengalaman saya, dibanding ketidaknyamanan Protobuf, risiko korupsi data pada JSON jauh lebih besar. Protobuf tertangkap sebagai compile error, sedangkan JSON meledak di produksi
  • Protobuf memang hebat, tetapi sayang tidak mendukung zero-copy. Format seperti Cap’n Proto bisa menghilangkan bottleneck serialisasi/deserialisasi

    • Namun dalam praktiknya, zero-copy justru bisa lebih lambat. Penyalinan di dalam cache nyaris gratis, tetapi menangani struktur dinamis secara langsung menimbulkan overhead. Dalam kebanyakan kasus, satu kali salin (one-copy) sudah cukup
    • Itu hanya klaim dari pemasaran Cap’n Proto; dalam kenyataannya perbedaan performanya kecil. Kedua format tetap memerlukan konversi antara tipe native ↔ biner. Tergantung payload, performanya mirip
    • Ini mungkin bukan masalah format, melainkan masalah implementasi library
  • Saya pernah membuat server untuk proyek NodeJS yang mendefinisikan seluruh API dengan .proto, lalu merespons dengan proto atau JSON sesuai Content-Type. Ini jauh lebih terstruktur dibanding Swagger. Hanya saja, sangat disayangkan Google tidak menyediakan fungsi seperti ini dalam library resmi. gRPC juga merepotkan karena bergantung pada HTTP/2. Sebagai tambahan, menurut saya Text proto adalah bahasa konfigurasi statis terbaik

    • Untuk tujuan seperti ini, Twirp cocok dipakai. Ia menangani Protobuf atau JSON di atas HTTP biasa
    • ConnectRPC juga menawarkan pendekatan serupa. Hanya saja, cakupan dukungannya masih belum jelas
  • Format biner impian saya adalah yang berbasis skema tetapi juga menyertakan skema di dalam pesan. Dengan begitu, file-nya bisa langsung dibaca lewat plugin vim. Saat menangani jutaan objek, menempelkan skema 1KB ke pesan 2GB bukanlah beban besar

    • Di internal Google sudah ada ekosistem Protobuf dengan skema tertanam seperti ini. Riegeli layak dilihat
    • Avro atau Yardl juga menawarkan pendekatan serupa
    • Namun pada layanan web, justru sering terjadi skemanya 200KB sementara pesannya 1KB. Dalam kasus seperti itu, ini jadi tidak efisien
    • Avro tetap merupakan alternatif yang baik
 
vipeen 2025-12-06

"Debugging memang sulit"

Lolos