38 पॉइंट द्वारा GN⁺ 2025-12-05 | 10 टिप्पणियां | WhatsApp पर शेयर करें
  • वेब API के standard के रूप में स्थापित JSON पढ़ने में आसान और flexible है, लेकिन performance और stability के मामले में इसकी सीमाएँ हैं
  • Protobuf(Protocol Buffers) सख्त type definition और automatic code generation के ज़रिए data structure को स्पष्ट रूप से सुनिश्चित करता है
  • Binary serialization का उपयोग करके यह JSON की तुलना में लगभग 3 गुना या उससे अधिक data size कम करता है और transfer speed बेहतर बनाता है
  • server और client एक ही .proto schema साझा करते हैं, इसलिए type mismatch या manual validation की ज़रूरत नहीं रहती
  • debugging कठिन हो सकती है, लेकिन performance, maintainability, development efficiency के लिहाज़ से Protobuf आधुनिक API के लिए अधिक उपयुक्त है

JSON की सार्वभौमिकता और सीमाएँ

  • JSON एक इंसान द्वारा आसानी से पढ़ा जा सकने वाला text format है, जिसमें सिर्फ console.log() से भी data देखा जा सकता है
  • वेब के साथ बेहतरीन integration की वजह से इसे JavaScript और backend framework ecosystem में व्यापक रूप से अपनाया गया है
  • यह field जोड़ने, हटाने और type बदलने की flexibility देता है, लेकिन इसी कारण structure mismatch या error की संभावना भी रहती है
  • Tool ecosystem समृद्ध है, इसलिए सिर्फ text editor या curl से भी इसे आसानी से संभाला जा सकता है
  • लेकिन इन फ़ायदों के बावजूद, performance और type safety के मामले में इससे बेहतर विकल्प मौजूद हैं

Protobuf का अवलोकन

  • Google द्वारा 2001 में विकसित और 2008 में सार्वजनिक किया गया binary serialization format
  • internal system और microservice के बीच communication में व्यापक रूप से उपयोग होता है
  • अक्सर यह गलतफ़हमी होती है कि इसे gRPC के साथ ही इस्तेमाल करना चाहिए, लेकिन Protobuf को स्वतंत्र रूप से HTTP API में भी इस्तेमाल किया जा सकता है
  • शुरुआत में binary format के सीधे न दिखने की वजह से इसकी पहुँच कम थी, लेकिन efficiency और stability के मामले में यह बहुत मज़बूत है

शक्तिशाली type system और code generation

  • Protobuf .proto file के माध्यम से data structure को स्पष्ट रूप से परिभाषित करता है
    • हर field का सख्त type, numeric identifier, और स्थिर नाम होता है
  • उदाहरण:
    message User {
      int32 id = 1;
      string name = 2;
      string email = 3;
      bool isActive = 4;
    }
    
  • protoc command के ज़रिए Dart, TypeScript, Kotlin, Swift, C#, Go, Rust जैसी कई भाषाओं के लिए automatic code generation का समर्थन
  • generated code के साथ serialization(writeToBuffer) और deserialization(fromBuffer) किया जाता है, और manual validation या parsing की ज़रूरत नहीं पड़ती
  • नतीजतन समय की बचत और maintainability में सुधार दोनों साथ मिलते हैं

Binary serialization की दक्षता

  • Protobuf text की जगह binary data में serialize होता है, इसलिए यह बेहद compact और तेज़ है
  • एक ही data (User object) के size की तुलना:
    • JSON: 86 bytes (whitespace हटाने पर 68 bytes)
    • Protobuf: 30 bytes
  • इसकी efficiency के कारण:
    • numbers के लिए varint encoding का उपयोग
    • text key की जगह numeric tag का उपयोग
    • whitespace और अनावश्यक syntax को हटाना
    • optional field optimization
  • नतीजतन bandwidth की बचत, response speed में सुधार, mobile data की बचत, और user experience बेहतर होता है

Dart आधारित Protobuf API उदाहरण

  • shelf package का उपयोग करके एक सरल HTTP server बनाया जाता है, जो User object को Protobuf में लौटाता है
  • server code के मुख्य बिंदु:
    • User() object बनाकर writeToBuffer() से serialize करना
    • response header में 'content-type': 'application/protobuf' सेट करना
  • client, http package और user.pb.dart का उपयोग करके Protobuf data को सीधे decode कर सकता है
  • server और client एक ही .proto schema साझा करते हैं, इसलिए data structure mismatch नहीं होता
  • यही तरीका Go, Rust, Kotlin, Swift, C#, TypeScript आदि में भी समान रूप से लागू किया जा सकता है

JSON के बचे हुए फ़ायदे

  • Protobuf में schema के बिना अर्थ समझना कठिन होता है
    • field name की जगह सिर्फ numeric identifier दिखते हैं, इसलिए इसे इंसान के लिए पढ़ना मुश्किल होता है
  • उदाहरण तुलना:
    • JSON: { "id": 42, "name": "Alice" }
    • Protobuf: 1: 42, 2: "Alice"
  • इसलिए Protobuf के लिए:
    • dedicated decoding tool की ज़रूरत होती है
    • schema management और version management अनिवार्य हैं
  • फिर भी, performance और efficiency के फ़ायदे इससे कहीं अधिक बड़े हैं

निष्कर्ष

  • Protobuf एक परिपक्व और high-performance serialization technology है, जिसे public API में भी पूरी तरह इस्तेमाल किया जा सकता है
  • gRPC के बिना भी यह सामान्य HTTP API में स्वतंत्र रूप से काम करता है
  • यह performance, robustness, error reduction, और development efficiency सभी को बेहतर बनाता है
  • अगली पीढ़ी की परियोजनाओं में Protobuf अपनाने का पर्याप्त मूल्य है

10 टिप्पणियां

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

https://msgpack.org/ यह कैसा है?

 
cosine20 2025-12-08

MessagePack भी अच्छा है।

 
savvykang 2025-12-06

मुझे लगता है कि जिस फ़ॉर्मैट के लिए debugging का कोई आधिकारिक decoder भी नहीं है, उसे mature बताना अपने आप में विरोधाभासी है।

 
jjw9512151 2025-12-05

हर टूल की तरह यह भी कोई सर्वगुणसंपन्न समाधान नहीं है, लेकिन मुझे लगता है कि Protobuf भी काफ़ी अच्छा टूल है.
खासकर जब एंबेडेड environment में कई भाषाओं के clients को high-volume, high-frequency (प्रति सेकंड 20 बार) डेटा भेजना पड़ता था, तब मैंने nanopb के साथ इसे काफ़ी साफ़-सुथरे तरीके से इस्तेमाल किया था.

 
ifmkl 2025-12-05

इतना सख्ती से करेंगे तो फिर क्या XML में नहीं आ जाएगा? haha

 
click 2025-12-06

अगर schema को भी dtd से define कर दिया जाए और parser side पर caching कर ली जाए, तो schema को सिर्फ़ एक बार भेजने जैसा असर भी होगा।

 
bakyeono 2025-12-05
  • मेरा आदर्श binary format schema-based हो, लेकिन message के अंदर schema भी शामिल हो। ऐसा होने पर उसे vim plugin से सीधे पढ़ा जा सकता है. लाखों objects को संभालते समय 2GB message में 1KB schema जोड़ना कोई बड़ा बोझ नहीं है
  • लेकिन web service में अक्सर उल्टा होता है: schema 200KB का और message 1KB का। ऐसे में यह अक्षम है

=> क्या schema को वैसे भी कम-से-कम एक बार भेजना ज़रूरी नहीं होता? JSON में भी schema गायब नहीं होता, बल्कि वह data में implicit रूप से शामिल होता है, इसलिए ऐसा नहीं है कि schema भेजा ही नहीं जा रहा। बल्कि हर item के साथ schema बार-बार duplicate होकर भेजा जाता है, इसलिए वह और भी अक्षम है। "schema-based होते हुए भी message के अंदर schema शामिल करने वाला format" काफ़ी अच्छा लग रहा है।

 
GN⁺ 2025-12-05
Hacker News राय
  • JSON में अक्सर अस्पष्ट या गैर-गारंटीड डेटा भेजा जाता है। फ़ील्ड छूट जाना, type errors, key में typo, undocumented structure जैसी कई समस्याएँ होती हैं। लेकिन एक लेख में दावा किया गया था कि Protobuf .proto फ़ाइल के ज़रिए message structure को स्पष्ट रूप से define करके ऐसी चीज़ों को असंभव बना देता है। हालांकि यह Protobuf की philosophy को गलत समझना है। proto3 में required fields का समर्थन ही नहीं है। आधिकारिक दस्तावेज़ (Protobuf Best Practices) में भी साफ़ लिखा है कि “required fields हानिकारक थे, इसलिए हटा दिए गए।” अंततः Protobuf client को भी JSON API की तरह defensive ढंग से लिखना पड़ता है

    • उस ब्लॉग में ऐसी गलतफ़हमियाँ और भी हैं। उदाहरण के लिए SVG के उपयोग के विरोध वाले लेख में vector format की freely scalable nature जैसे फ़ायदे पर ध्यान नहीं दिया गया
    • समस्या का मूल सिर्फ भाषा या client/server implementation का अंतर है। मैं Go के Marshalling concept का इस्तेमाल करके client पर Gooey framework उपयोग कर रहा हूँ। Go की सीमाओं को पार कर लें तो इसे बहुत type-safe तरीके से इस्तेमाल किया जा सकता है। बस json:"-" से private fields को रोकना ज़रूरी है। मेरा प्रोजेक्ट Gooey में देखा जा सकता है
    • यह लेख serialization format और contract की अवधारणाओं को मिला रहा है
    • network systems में encoding method चाहे जो हो, data skew की समस्या हमेशा रहती है। हाँ, Protobuf decoding के बाद static typed object देता है। JSON में भी validation किया जा सकता है, लेकिन ज़्यादातर लोग ऐसा नहीं करते। नतीजा यह होता है कि JSON object इधर-उधर mutate होता रहता है और उसकी internal structure पर किसी को भरोसा नहीं रहता
    • शायद मूल लेखक सिर्फ यह कहना चाहता था कि Protobuf में missing fields default values से initialize हो जाते हैं। यह “required” field की अवधारणा से अलग बात है
  • compressed JSON काफ़ी उपयोगी है, और initial communication cost कम होती है। फ़ील्ड छूट जाएँ या type बदल जाए तो दिक्कत होती है, लेकिन पूरी तरह typed structure design करना और version sync के लिए process बनाना ज़्यादातर लोग ठीक से नहीं कर पाते। आख़िर में कम human cost वाला तरीका जीतता है। इसलिए JSON तब तक ग़ायब नहीं होगा जब तक उससे कम human communication cost वाला कोई विकल्प नहीं आ जाता

    • सही बात। ज़्यादातर architects, gRPC जैसी स्पष्ट ज़रूरत के बिना proto पर विचार ही नहीं करते। जब तक console.log() से तुरंत debug किया जा सकने वाला विकल्प नहीं आता, JSON को replace करना मुश्किल है
    • debugging भी JSON की ताकत है। बस खोलिए और पढ़ लीजिए। जबकि Protobuf के लिए tooling चाहिए
    • बात सही है। लेकिन लोग design phase में 15 मिनट और देने के बजाय, बाद में 3 महीने तक समस्याओं को reverse-engineer करना पसंद करते हैं
    • JSON शायद COBOL की तरह पूरी तरह कभी गायब न हो, लेकिन नए projects में इसे इस्तेमाल करने की कोई खास वजह नहीं है
  • Protobuf परफ़ेक्ट नहीं है। server और client अलग-अलग समय पर deploy हों और spec version अलग हो जाए, तो safety टूट जाती है। ID reuse पर रोक, unknown-field copying जैसी चीज़ों से इसे कुछ हद तक कम किया जा सकता है, लेकिन distributed systems मूल रूप से complex होते हैं। फिर भी protobuf3 ने protobuf2 की बहुत-सी समस्याएँ हल कीं। पहले यह पता नहीं चलता था कि default value explicitly set की गई थी या field missing थी, लेकिन अब message type से यह हल हो जाता है

    • JSON हो या Protobuf, version compatibility tests को CI pipeline में enforce करना ज़रूरी है, तभी safety मिलती है
    • कोई भी type system network पार करते ही टूट जाता है
  • लेख में इसे “अत्यंत कुशल” कहा गया, लेकिन gzip का कोई ज़िक्र नहीं है। ज़्यादातर text data पहले से ही auto-compress होकर भेजा जाता है। इसलिए Protobuf की तुलना gzip किए गए JSON से होनी चाहिए

    • मैंने भी कई binary formats test किए हैं, लेकिन अंत में gzipped JSON बहुत ज़्यादा efficient निकला
    • JSON की कमी serialization/deserialization speed है। बाकी चीज़ें धीरे-धीरे सुधारी जा सकती हैं
    • streaming Brotli/zstd JSON/HTML पर भी विचार किया जा सकता है। connection बनाए रखने के दौरान compression window का फायदा लिया जा सकता है
    • संबंधित संदर्भ: Auth0 का Protobuf performance comparison लेख
    • JSON और mod_deflate का संयोजन महसूस होने लायक बड़ा फ़र्क पैदा करता है
  • बेहतर protocol की वकालत करना अच्छी बात है, लेकिन यह कहना मुश्किल है कि Protobuf efficiency और usability दोनों में JSON की जगह ले सकता है। Protobuf अपनी strict schema की वजह से उन क्षेत्रों में कमज़ोर पड़ता है जहाँ JSON अच्छा काम करता है। बल्कि CBOR JSON के विकल्प के रूप में ज़्यादा उपयुक्त लगता है। CBOR, JSON की तरह flexible है, लेकिन encoding अधिक compact है

    • लेकिन Protobuf की strict schema ही उसका फ़ायदा भी हो सकती है। ज़्यादातर APIs JSON schema publish नहीं करतीं। मैंने ajv और superstruct से validation किया है, लेकिन Protobuf में इसकी ज़रूरत नहीं पड़ती
    • अच्छा होगा अगर browser CBOR API को सीधे support करें। internal implementation तो पहले से है, इसलिए यह कठिन नहीं होना चाहिए
  • 1984 का ASN.1 पहले से वह काम अधिक flexibility के साथ करता है जो Protobuf करता है। DER encoding का इस्तेमाल करें तो यह इतना भी बुरा नहीं है। ASN.1 DER उदाहरण देखा जा सकता है। Protobuf जो हासिल करता है, उसके मुकाबले बहुत ज़्यादा जटिल है

    • ASN.1 में features बहुत ज़्यादा हैं। अगर सब support करें तो बेहद जटिल library बन जाती है, और अगर कुछ ही support करें तो वह फिर standard ASN.1 नहीं रह जाता
    • मैं ASN.1 DER को पसंद करता हूँ। मैंने खुद C में DER encoder/decoder implement करके FOSS के रूप में जारी किया है। साथ ही एक extensible “ASN.1X” बनाया है जो JSON के data model को पूरी तरह शामिल करता है
    • लेकिन SNMP जैसे systems में ASN.1 की अत्यधिक flexibility ही समस्या बन गई। हर vendor ने इसे अपने हिसाब से बढ़ा लिया
    • Google के अंदर भी Protobuf serialization/deserialization पर CPU बहुत खर्च होता था
    • ASN.1 overengineered है, इसलिए उसे support करना मुश्किल है। inheritance जैसी सुविधाएँ अनावश्यक हैं
  • मैंने पूरे production system को Protobuf से बनाया था, लेकिन उसका management अपने आप में पीड़ादायक था। तकनीकी रूप से यह अच्छा दिखता है, लेकिन व्यवहार में JSON कहीं ज़्यादा सरल है

    • JSON की readability और debugging convenience को कम करके नहीं आँका जा सकता। ज़्यादातर teams short-term efficiency के लिए JSON चुनती हैं
    • जानना दिलचस्प होगा कि समस्या क्या थी। मेरे अनुभव में Protobuf की असुविधा से ज़्यादा ख़तरा JSON में data corruption risk का है। Protobuf में चीज़ें compile errors से पकड़ में आ जाती हैं, जबकि JSON production में फटता है
  • Protobuf बेहतरीन है, लेकिन इसमें zero-copy support न होना खलता है। Cap’n Proto जैसे formats serialization/deserialization bottleneck हटा देते हैं

    • लेकिन व्यवहार में zero-copy उल्टा धीमा भी हो सकता है। cache के भीतर copy करना लगभग मुफ़्त है, लेकिन dynamic structure को सीधे handle करने पर overhead आता है। ज़्यादातर मामलों में एक बार copy होना ही काफ़ी है
    • यह Cap’n Proto की marketing से आया दावा है; व्यवहार में performance difference बहुत मामूली होता है। दोनों formats में native types ↔ binary conversion की ज़रूरत होती है। payload के अनुसार performance लगभग समान रहती है
    • यह format की नहीं, library implementation की समस्या भी हो सकती है
  • मैंने एक NodeJS project में .proto से पूरा API define किया था, और Content-Type के आधार पर proto या JSON में response देने वाला server बनाया था। यह Swagger से कहीं ज़्यादा structured है। बस अफ़सोस यह है कि Google ने ऐसी सुविधा official library में नहीं दी। gRPC, HTTP/2 dependency की वजह से असुविधाजनक है। वैसे मेरे हिसाब से Text proto सबसे बेहतरीन static configuration language है

    • ऐसे उपयोग के लिए Twirp उपयुक्त है। यह साधारण HTTP पर Protobuf और JSON दोनों संभालता है
    • ConnectRPC भी ऐसा ही approach देता है। हालांकि इसकी support range अभी भी कुछ अस्पष्ट है
  • मेरा सपना एक ऐसे binary format का है जो schema-based भी हो और message के भीतर schema भी शामिल करे। तब उसे vim plugin से सीधे पढ़ा जा सकेगा। जब लाखों objects हों, तो 2GB message में 1KB schema जोड़ना कोई बड़ा बोझ नहीं है

    • Google के अंदर पहले से ऐसा embedded-schema Protobuf ecosystem मौजूद है। Riegeli देखना उपयोगी हो सकता है
    • Avro या Yardl भी ऐसा ही approach देते हैं
    • लेकिन web services में अक्सर उल्टा होता है: schema 200KB और message 1KB का होता है। तब यह अप्रभावी हो जाता है
    • Avro अब भी एक अच्छा विकल्प है
 
vipeen 2025-12-06

"डिबगिंग मुश्किल है"

छूट गया