JSON format करें

JSON चिपकाइए और उसे पढ़िए। वह ब्राउज़र के भीतर मौजूद parser से पढ़ी जाती है और आपके चुने हुए indent के साथ दोबारा लिखी जाती है, इसलिए जो बाहर आता है वह ठीक वही दस्तावेज़ है — ऐसा टेक्स्ट नहीं जिसमें पंक्ति-विच्छेद ठूँस दिए गए हों। कुछ अपलोड नहीं होता: अगर आप जो देख रहे हैं वह ग्राहकों के डेटा वाला API जवाब है, तो वह आपके ही टैब में रहता है।

तुलना से पहले काम की चीज़। Array का क्रम कभी नहीं छुआ जाता: array एक अनुक्रम है।

नतीजा

आप लिखते जाइए, जवाब यहाँ आता जाएगा।

  • कहाँ चलता है

    कुछ भी अपलोड नहीं होता, क्योंकि कोई फ़ाइल है ही नहीं — गणना इसी पन्ने में होती है।

  • न कतार, न खाता

    यह उतनी ही तेज़ी से जवाब देता है जितनी आपकी मशीन देती है, और कभी नहीं पूछता कि आप कौन हैं।

  • जितनी बार चाहें

    न कुछ गिना जाता है, न कोई सीमा है — दोबारा जवाब देने में हमारा कुछ ख़र्च नहीं होता।

काम कैसे करता है

  1. JSON खाने में चिपकाइए।
  2. Indent चुनिए, और अगर दो दस्तावेज़ों की तुलना करनी है तो कुंजियाँ क्रम में लगा लीजिए।
  3. नतीजा कॉपी कर लीजिए। वह डिवाइस से बाहर नहीं गया।

यह parse होती है, सजाई नहीं जाती

यहाँ format करने का मतलब है पूरा दस्तावेज़ पढ़ना और उसे दोबारा लिखना। सस्ता विकल्प — जहाँ कोई कोष्ठक दिखे वहाँ पंक्ति-विच्छेद और स्पेस ठूँसते जाना — तब तक चलता है जब तक किसी स्ट्रिंग के भीतर कोई कोष्ठक न आ जाए, और तब वह दस्तावेज़ को इस तरह बिगाड़ता है कि वह फिर भी JSON जैसा दिखता रहता है।

काम का नतीजा यह है कि format करना ख़ुद एक जाँच भी है। अगर कुछ बाहर आया तो दस्तावेज़ वैध था; अगर नहीं, तो नहीं था — और उसी के लिए validate वाला पन्ना है, जो बताता है कि किस पंक्ति पर अटकन है। जो formatter कभी विफल नहीं होता वह formatter असल में आपकी दी हुई चीज़ पढ़ ही नहीं रहा।

दो स्पेस, चार, या एक tab

दो स्पेस वही है जो `JSON.stringify` से indent माँगने पर निकलता है और जो JavaScript के लगभग सारे औज़ार डिफ़ॉल्ट रखते हैं। चार Python और Java की दुनिया से आता है। Tab बाइट बचाता है और हर किसी को अपने एडिटर में चौड़ाई चुनने देता है।

तीनों में से कोई भी दस्तावेज़ नहीं बदलता: parser के लिए तत्वों के बीच का ख़ाली स्थान होता ही नहीं। यह सिर्फ़ तब मायने रखता है जब नतीजा किसी repository में जा रहा हो, जहाँ मिली-जुली परिपाटियाँ उन पंक्तियों में अंतर दिखाती हैं जिन्हें किसी ने छुआ तक नहीं — यही वजह है कि एक परिपाटी तय कर लेना और उसे औज़ार से लगवाना, इंसान से नहीं, बेहतर है।

कुंजियों का क्रम और array का क्रम

JSON object का कोई तय क्रम नहीं होता, इसलिए दो सेवाएँ वही डेटा कुंजियों के अलग-अलग क्रम में लौटा सकती हैं। उन्हें वर्णक्रम में लगा देना टेक्स्ट की तुलना को काम की तुलना में बदल देता है, और diff या contract test से पहले ठीक यही चाहिए होता है।

Array इसका उलटा है: उसका क्रम ख़ुद डेटा का हिस्सा है। यहाँ उसे कभी नहीं छुआ जाता, और यह असंतुलन जान-बूझकर है। जो औज़ार array भी क्रम में लगा दे वह ऐसे दस्तावेज़ बनाता है जिनकी तुलना अच्छी होती है और जिनका मतलब कुछ और होता है — और इससे बुरा संयोजन कोई नहीं।

संख्याएँ कहाँ से बिगड़ने लगती हैं

JSON संख्याओं को टेक्स्ट की तरह लिखती है और JavaScript उन्हें दोहरी परिशुद्धता के दशमलव की तरह पढ़ता है। 9,00,71,99,25,47,40,991 से बड़े पूर्णांक अंक खोने लगते हैं: 19 अंकों की कोई पहचान-संख्या बदली हुई लौटती है, और चूँकि नतीजा अब भी वैध संख्या जैसा दिखता है, किसी को पता नहीं चलता।

यह हर उस प्रक्रिया पर लागू है जो JavaScript के parser से गुज़रती है, इस पन्ने समेत, और ऐसा होने पर बता दिया जाता है। आम वजह Twitter और Discord जैसी snowflake पहचान-संख्याएँ और कुछ डेटाबेस अनुक्रम होते हैं। हल उनके बनाने वाले के पास है: ऐसे मान स्ट्रिंग के रूप में जाने चाहिए, तब वे हर चरण से बिना बदले निकल जाते हैं।

JSON में जो नहीं है

न टिप्पणियाँ हैं, न आख़िरी अल्पविराम, न इकहरे उद्धरण-चिह्न, न बिना उद्धरण वाली कुंजियाँ। इनमें से हर एक JavaScript से आई आदत है, और हर एक parser को ऐसे संदेश के साथ रोक देती है जो सही जगह की ओर लगभग कभी इशारा नहीं करता।

जिसे कॉन्फ़िग में टिप्पणियाँ चाहिए उसके पास तीन रास्ते हैं: ऐसा फ़ॉर्मैट लीजिए जो उन्हें मानता हो — YAML, TOML, JSON5 —, या `_comment` जैसा कोई फ़ील्ड रखिए जिसे जान-बूझकर अनदेखा किया जाए, या प्रोसेस करने से पहले उन्हें हटा दीजिए। तीसरा सबसे प्रचलित और सबसे नाज़ुक है, क्योंकि दोहरी तिरछी लकीर किसी URL के भीतर भी आती है।

देवनागरी बची रहती है, escape में नहीं बदलती

नतीजा UTF-8 में जैसा है वैसा निकलता है, ASCII से बाहर के अक्षरों को `\uXXXX` escape में बदले बिना। दोनों रूप वैध JSON हैं और एक ही चीज़ कहते हैं, पर पहला पढ़ा जाता है और दूसरा नहीं: «नमस्ते» को `\u0928\u092e\u0938\u094d\u0924\u0947` लिखना सही है और पढ़ने लायक़ नहीं।

कुछ लाइब्रेरियाँ डिफ़ॉल्ट रूप से escape करती हैं क्योंकि वे मान लेती हैं कि रास्ता साफ़ नहीं है, जो बहुत पहले से सच नहीं रहा। अगर आपका डेटा ऐसी escape शृंखलाओं के साथ आता है तो यह formatter उन्हें वापस नहीं बदलता — वे उस दस्तावेज़ का हिस्सा हैं जैसा आपको मिला, और उन्हें बदलना प्रस्तुति नहीं बल्कि डेटा को दोबारा लिखना होता।

यह किस काम आता है और किस काम नहीं

यह पन्ना पढ़ने की समस्या हल करता है: सामने एक दस्तावेज़ है और उसका आकार दिखता नहीं। यही चाहिए होता है जब API का जवाब एक पंक्ति में आए, जब किसी लॉग फ़ील्ड के भीतर JSON हो, या जब कोई कॉन्फ़िग का ढेला किसी टिकट में चिपका दे।

यह उलटी समस्या हल नहीं करता। उसे एक पंक्ति में लाने के लिए minify वाला पन्ना है, और यह जानने के लिए कि कोई चीज़ उसे मना क्यों कर रही है, validate वाला पन्ना है, जो पंक्ति और कॉलम देता है। तीनों एक ही इंजन साझा करते हैं और अलग इसलिए हैं कि वे तीन अलग क्षण हैं, तीन अलग सवालों के साथ।

Repository में सजी हुई, बाहर जाते समय सिकुड़ी हुई

किसी version-नियंत्रित फ़ाइल के भीतर सिकुड़ी हुई JSON हर बदलाव को एक बदली हुई पंक्ति में बदल देती है। Diff सब-कुछ-या-कुछ-नहीं हो जाता, समीक्षा असंभव हो जाती है, और merge का टकराव उन दो फ़ील्ड के बजाय पूरे दस्तावेज़ को छूता है जिनकी बात थी।

जो बँटवारा चलता है वह साफ़ है: repository में सजी हुई, परोसते समय सिकुड़ी हुई। इन दोनों हालतों के बीच ठीक वह क़दम है जो किसी build प्रक्रिया को ख़ुद उठाना चाहिए, और अपने आप में कोई भी रूप सही या ग़लत नहीं है — वे अपनी जगह पर सही हैं।

जब हिंदी अक्षर अपने-आप में एक बाइट-समस्या बन जाते हैं

Format करने से दस्तावेज़ का आकार बढ़ता है, और यह बढ़त बाइट में गिनी जाती है, अक्षरों में नहीं। देवनागरी के हर अक्षर की तीन बाइट के चलते हिंदी सामग्री वाला दस्तावेज़ अपने अक्षरों की गिनती से लगभग तीन गुना भारी होता है, इसलिए किसी सीमित लंबाई वाले फ़ील्ड में «यह तो पंद्रह सौ अक्षर ही है» वाला हिसाब वहाँ फेल होता है।

व्यावहारिक नतीजा: अगर कोई कतार का संदेश, कोई कॉन्फ़िग वेरिएबल या कोई डेटाबेस कॉलम बिना किसी साफ़ वजह के भर जाता है, तो सजावट हटाने से पहले यह गिन लीजिए कि सामग्री में हिंदी है या नहीं। Minify वाला पन्ना बचत को बाइट में दिखाता है, ठीक इसी कारण से।

DPDP Act के लिहाज़ से इसका क्या मतलब है

किसी JSON payload में अक्सर ठीक वही होता है जिसे हिलाना नहीं चाहिए: ग्राहकों के रिकॉर्ड, ऑर्डर का डेटा, नाम-पते वाला कोई webhook, कभी-कभी KYC के खाने। चूँकि यहाँ parse और लेखन उसी पन्ने पर होता है, वह सामग्री हम तक पहुँचती ही नहीं और उस पर हमारी कोई प्रोसेसिंग की भूमिका बनती ही नहीं।

यह नेटवर्क पैनल में साबित होता है: औज़ार चलाते हुए ऐसी कोई रिक्वेस्ट नहीं निकलती जो आपका दस्तावेज़ ले जाए। यही वजह है कि यह औज़ार वहाँ इस्तेमाल हो सकता है जहाँ सर्वर वाला रूप किसी आंतरिक नीति से टकरा जाता, और जाँचने में एक मिनट लगता है।

JSON format करें: आम सवाल

क्या format करने से मेरा दस्तावेज़ बदल जाता है?

नहीं। वह parse होकर दोबारा लिखा जाता है, इसलिए डेटा का ढाँचा वही रहता है; सिर्फ़ तत्वों के बीच का ख़ाली स्थान बदलता है, जो parser के लिए होता ही नहीं। Array का क्रम कभी नहीं छुआ जाता।

मुझे कौन-सा indent चुनना चाहिए?

दो स्पेस अगर मंज़िल JavaScript है, चार अगर वह Python या Java की दुनिया से आती है, tab अगर आप चाहते हैं कि चौड़ाई हर कोई ख़ुद चुने। Parser के लिए फ़र्क़ नहीं; फ़र्क़ तब पड़ता है जब नतीजा किसी repository में जाए।

मेरी लंबी पहचान-संख्या क्यों बदल जाती है?

क्योंकि JavaScript संख्याओं को दोहरी परिशुद्धता के दशमलव की तरह पढ़ता है और 9,00,71,99,25,47,40,991 से बड़े पूर्णांक अंक खो देते हैं। ऐसी पहचान-संख्याओं को JSON में स्ट्रिंग के रूप में चलना चाहिए; तब वे हर चरण से बिना बदले निकलती हैं।

टिप्पणियों वाली मेरी JSON मना क्यों की जाती है?

क्योंकि JSON में टिप्पणियाँ होती ही नहीं। न आख़िरी अल्पविराम, न बिना उद्धरण वाली कुंजियाँ। अगर कॉन्फ़िग में टिप्पणियाँ चाहिए तो उपयुक्त फ़ॉर्मैट YAML, TOML या JSON5 है।

क्या मेरा दस्तावेज़ अपलोड होता है?

नहीं। वह इसी पन्ने पर, आपके ब्राउज़र में parse और लिखा जाता है। जाँचने का तरीक़ा नेटवर्क पैनल है: चलाते हुए ऐसी कोई रिक्वेस्ट नहीं निकलती जो आपकी JSON ले जाए।

और टूल्स