प्रॉम्प्ट और दायरा
एक पब्लिक API को एक Features रिस्पॉन्स फ़ील्ड की आवश्यकता है जिसमें क्षमता के नाम, प्राथमिकताएं और प्रयोग (experiment) पैरामीटर्स शामिल हों। कई भाषाओं के क्लाइंट्स, CDNs, गेटवे और SDKs इसे पढ़ेंगे; लेगेसी क्लाइंट केवल अज्ञात फ़ील्ड्स को अनदेखा कर सकते हैं। फ़ील्ड फॉर्मेट, सीरियलाइजेशन और पार्सिंग नियम, कम्पैटिबिलिटी नीति और वेरिफिकेशन योजना डिज़ाइन करें।
यह बैकएंड API-कॉन्ट्रैक्ट से जुड़ा प्रश्न है। मुख्य बात एक "स्ट्रिंग जैसे हेडर" को एक इंटरऑपरेबल प्रोटोकॉल में बदलना है। RFC 8941 सामान्य Item, List, Dictionary और पैरामीटर मॉडल को परिभाषित करता है, और RFC 9651 इसका संशोधन है। RFC 9110 के अनुसार नए फ़ील्ड्स को अपने व्याकरण (grammar) को निर्दिष्ट करना और खतरनाक कंट्रोल कैरेक्टर्स को अस्वीकार करना आवश्यक है। आपको प्रत्येक RFC एल्गोरिदम को लागू करने की आवश्यकता नहीं है, लेकिन आपको सीमाओं को परिभाषित करना होगा।
इंटरव्यूअर क्या टेस्ट कर रहा है
इंटरव्यूअर यह देखना चाहता है कि क्या आप कॉमा-सेपरेटेड टेक्स्ट को जोड़ने के बजाय List, Dictionary, या Item चुनने से पहले सिमेंटिक्स (semantics) को परिभाषित करते हैं। एक मजबूत उत्तर में सेंडर सीरियलाइजेशन, रिसिपिएंट पार्सिंग, अज्ञात मेंबर्स, डुप्लिकेट-फ़ील्ड संयोजन, आकार सीमाएं और टेलीमेट्री शामिल होती हैं।
एक कमजोर उत्तर केवल एक नमूना मान दिखाता है। एक मजबूत उत्तर यह समझाता है कि क्षमता सेट एक Dictionary क्यों है, पैरामीटर कुंजियाँ लोअरकेस में क्यों हैं, मनमाने गैर-ASCII टेक्स्ट को String में क्यों नहीं छिपाया जाना चाहिए, और पार्स विफलता किसी फीचर को गलती से सक्षम होने से कैसे रोकती है। वर्तमान बैकएंड API इंटरव्यू गाइड भी स्थिर अनुबंधों, बैकवर्ड कम्पैटिबिलिटी और विफलता मोड पर जोर देते हैं।
पहले स्पष्ट करने योग्य प्रश्न
फ़ील्ड सिमेंटिक्स और ट्रस्ट बाउंड्री
पुष्टि करें कि क्या यह एक हिंट (hint), ऑथराइजेशन निर्णय या व्यावसायिक तथ्य है। यदि यह अनुमति, बिलिंग या सुरक्षा को प्रभावित करता है, तो सर्वर आधिकारिक रहता है और उसे क्लाइंट इको (echo) पर भरोसा नहीं करना चाहिए। पूछें कि क्या फ़ील्ड को कैश किया जा सकता है और क्या इसका मान उपयोगकर्ता के आधार पर भिन्न होता है।
प्रकार और कम्पैटिबिलिटी एनवलप
पूछें कि क्या मान एक अनियंत्रित (unordered) क्षमता सेट है, एक क्रमित प्राथमिकता सूची है, या एक संस्करण पहचानकर्ता है। पुष्टि करें कि क्या पुराने क्लाइंट्स को काम करना जारी रखना चाहिए, क्या नए पैरामीटर दिखाई दे सकते हैं, और क्या गेटवे डुप्लिकेट फ़ील्ड लाइनों को जोड़ते हैं। वे उत्तर कंटेनर प्रकार और अज्ञात-सदस्य नीति निर्धारित करते हैं।
विफलता और संसाधन बजट
तय करें कि क्या अमान्य इनपुट के कारण पूरा फ़ील्ड, एक सदस्य, या रिस्पॉन्स अनदेखा किया जाता है। बाइट, सदस्य, नेस्टिंग और पार्सिंग-समय की सीमाएं निर्धारित करें; ये विकल्प DoS सीमा का हिस्सा बन जाते हैं।
30-सेकंड का उत्तर ढांचा
"मैं इसे स्ट्रिंग में छिपे JSON के रूप में नहीं, बल्कि एक संस्करण-योग्य (versionable) मशीन अनुबंध के रूप में परिभाषित करूँगा। एक क्षमता सेट एक Dictionary का उपयोग करता है, जिसमें प्रत्येक कुंजी एक बूलियन या पैरामीटरयुक्त Item ले जाती है; कुंजियाँ और पैरामीटर RFC सीरियलाइजेशन नियमों का पालन करते हैं, और अज्ञात सदस्यों को अनदेखा कर दिया जाता है। सर्वर प्रतिबंधित ASCII का उत्सर्जन करता है और कुल आकार तथा सदस्य सीमाओं को लागू करता है। प्राप्तकर्ता उसी व्याकरण का उपयोग करते हैं, अमान्य सिंटैक्स को फ़ील्ड अनुपस्थिति के रूप में मानते हैं, और कभी यह अनुमान नहीं लगाते कि कोई फीचर सक्षम है। मैं गेटवे पर डुप्लिकेट-फ़ील्ड संयोजन और कैश भिन्नता का परीक्षण करूँगा, पहले शैडो-पार्स करूँगा, और रोलआउट से पहले पार्स विफलताओं, फ़ील्ड आकार और आकस्मिक फीचर सक्षमता की तुलना करूँगा।"
चरण-दर-चरण समाधान
चरण 1: कंटेनर चुनने से पहले मान का मॉडल बनाएं
क्षमता स्विच के लिए Dictionary का उपयोग करें, जैसे search;v=2, upload=?1। जब प्रत्येक सदस्य का कोई सार्थक क्रम या पैरामीटर हो तो List का उपयोग करें। एक संस्करण या नीति नाम के लिए Item का उपयोग करें। केवल सुविधा के लिए हेडर के अंदर JSON न रखें: मध्यवर्तियों और SDKs को अभी भी एक विशेष पार्सर की आवश्यकता होगी।
चरण 2: एक एक्सटेंसिबल फ़ील्ड परिभाषित करें
search और upload जैसी कुंजियाँ परिभाषित करें; v=2 और tier="pro" जैसे पैरामीटर केवल संरचित-फ़ील्ड व्याकरण द्वारा अनुमत प्रकारों का उपयोग करते हैं। पैरामीटर कुंजियाँ लोअरकेस में होती हैं। डिस्प्ले टेक्स्ट को फ़ील्ड से बाहर रखें, या प्रत्येक मध्यवर्ती की जाँच करने के बाद स्पष्ट रूप से समर्थित Display String एक्सटेंशन का उपयोग करें। प्रत्येक सदस्य के सिमेंटिक्स, डिफ़ॉल्ट और अमान्य-मान के परिणाम को दस्तावेज़ित करें।
Features: search;v=2, upload=?1सीरियलाइजेशन नियतात्मक (deterministic) होना चाहिए ताकि समकक्ष मान अनावश्यक कैश-की या हस्ताक्षर अंतर उत्पन्न न करें। प्राप्तकर्ताओं को व्याकरण-जागरूक पार्सर को split(',') से प्रतिस्थापित नहीं करना चाहिए; कॉमा, कोष्ठक, उद्धरण और पैरामीटर की सीमाएं परिभाषित होती हैं।
चरण 3: डुप्लिकेट फ़ील्ड्स और अज्ञात सदस्यों को निर्दिष्ट करें
पहले बताएं कि क्या दोहराई गई लाइनें अनुमत हैं। यदि फ़ील्ड एक Dictionary है, तो मिडलवेयर लाइनों को जोड़ सकता है, इसलिए अनुबंध को संयुक्त अर्थ और डुप्लिकेट कुंजियों के लिए एक विरोध नियम को परिभाषित करना होगा। डिफ़ॉल्ट रूप से अज्ञात कुंजियों और वैकल्पिक पैरामीटर्स को अनदेखा करें। अमान्य प्रकार वाली किसी ज्ञात कुंजी के लिए, या तो उस सदस्य को या पूरे फ़ील्ड को हटा दें, लेकिन इस विकल्प को मानक (normative) बनाएं। पार्सिंग विफल होने के कारण सुरक्षा स्विच कभी सक्षम नहीं होना चाहिए।
चरण 4: एक सख्त लेकिन उपयोगी पार्सिंग सीमा का निर्माण करें
गहन पार्सिंग से पहले कुल बाइट्स, सदस्यों, नेस्टिंग की गहराई और CPU समय को सीमित करें। CR, LF, NUL और फ़ील्ड व्याकरण के बाहर के अन्य वर्णों को अस्वीकार करें। बाहरी इनपुट को निरंतर-समय (constant-time) पार्सिंग की आवश्यकता नहीं होती है, लेकिन अपवाद पथों को बार-बार एक विशाल मान को पार्स नहीं करना चाहिए। संभावित रूप से संवेदनशील पूरे फ़ील्ड को लॉग किए बिना वर्गीकृत विफलताओं को रिकॉर्ड करें।
चरण 5: कैशिंग, हस्ताक्षर और विकास को संभालें
यदि फ़ील्ड उपयोगकर्ता या प्रयोग समूह (cohort) के आधार पर भिन्न होता है, तो सही Vary रिस्पॉन्स व्यवहार या निजी कैशिंग का उपयोग करें; अन्यथा CDN एक उपयोगकर्ता की क्षमताओं को दूसरे के सामने उजागर कर सकता है। यदि फ़ील्ड HTTP Message Signatures द्वारा कवर किया गया है, तो हस्ताक्षरकर्ताओं और सत्यापनकर्ताओं को समान विहित (canonical) संरचित मान की आवश्यकता होती है। अतिरिक्त कुंजियाँ और वैकल्पिक पैरामीटर पुराने क्लाइंट्स के लिए अनदेखा करने योग्य रहने चाहिए; सिमेंटिक्स को हटाने या बदलने के लिए एक संस्करण या माइग्रेशन विंडो की आवश्यकता होती है।
चरण 6: रोलआउट और विपरीत उदाहरणों के साथ डिज़ाइन को सिद्ध करें
व्यवहार को बदले बिना पहले शैडो-पार्स करें, फिर एक छोटे आंतरिक समूह के लिए सक्षम करें। डुप्लिकेट कुंजियों, खाली सूचियों, टूटे हुए उद्धरणों, अज्ञात पैरामीटर्स, बड़े आकार के फ़ील्ड्स, प्रॉक्सी संयोजन और कैश बेमेल का परीक्षण करें। फ़ील्ड के साथ और उसके बिना पार्स सफलता, आकस्मिक सक्षमता, रिस्पॉन्स बाइट्स, CPU, कैश हिट्स और SDK संस्करणों की तुलना करें। प्रत्येक पार्स विफलता सुरक्षित डिफ़ॉल्ट पर लौटती है।
उच्च गुणवत्ता वाला नमूना उत्तर
मैं इसे एक प्रोटोकॉल-डिज़ाइन समस्या के रूप में मानूंगा। पहले मैं पुष्टि करूँगा कि क्या फ़ील्ड केवल एक क्षमता संकेत है; यदि यह ऑथराइजेशन को नियंत्रित करता है, तो सर्वर आधिकारिक रहता है। एक क्षमता सेट के लिए मैं एक Structured Field Dictionary चुनूंगा और प्रत्येक कुंजी को एक बूलियन या पैरामीटरयुक्त Item के रूप में परिभाषित करूँगा। मैं अनियंत्रित क्षमताओं के लिए List का उपयोग नहीं करूँगा। अनुबंध सीरियलाइजेशन, पैरामीटर प्रकार, डुप्लिकेट लाइनें, अज्ञात सदस्य और अमान्य-मान के परिणामों को निर्दिष्ट करेगा।
सेंडर प्रतिबंधित ASCII उत्सर्जित करता है और फ़ील्ड-आकार तथा सदस्य सीमाओं को लागू करता है। प्राप्तकर्ता कॉमा पर विभाजित करने के बजाय RFC-अनुरूप पार्सर का उपयोग करता है, कंट्रोल कैरेक्टर्स को अस्वीकार करता है, अज्ञात कुंजियों को अनदेखा करता है, और गलत प्रकार वाली ज्ञात कुंजी को अनुपस्थित मानता है। गेटवे का एक निश्चित डुप्लिकेट-संयोजन नियम होता है, कभी भी आकस्मिक "अंतिम मान की जीत" नहीं।
मैं कैश और हस्ताक्षर व्यवहार की भी समीक्षा करूँगा: उपयोगकर्ता-विशिष्ट क्षमताओं के लिए Vary, निजी कैशिंग, या कोई कैशिंग नहीं की आवश्यकता होती है, और हस्ताक्षर के दोनों पक्षों को मान को समान रूप से सामान्यीकृत करना चाहिए। मैं शैडो-पार्स करूँगा, फिर पार्स विफलताओं, आकस्मिक सक्षमता, आकार और CPU की निगरानी करते हुए फ़ील्ड को कैनरी रोलआउट करूँगा। पुराने क्लाइंट फ़ील्ड को अनदेखा करना जारी रखते हैं; केवल वे क्लाइंट जो स्पष्ट रूप से संस्करण का समर्थन करते हैं, नए व्यवहार को सक्षम करते हैं।
सामान्य गलतियाँ
- स्ट्रिंग हेडर में JSON डालना → प्रॉक्सी और SDKs को अभी भी कस्टम पार्सिंग की आवश्यकता होती है, जिसमें असंगत एस्केपिंग और डुप्लिकेट सिमेंटिक्स होते हैं → RFC Item, List, या Dictionary मॉडल का उपयोग करें और सदस्य के अर्थ को दस्तावेज़ित करें।
split(',')के साथ पार्स करना → उद्धरण, आंतरिक सूचियां और पैरामीटर डिलीमीटर गलत तरीके से कट जाते हैं → एक व्याकरण-जागरूक पार्सर और अमान्य-सिंटैक्स परीक्षणों का उपयोग करें।- प्रत्येक अज्ञात पैरामीटर पर विफल होना → नए सेंडर पुराने क्लाइंट्स के साथ इंटरऑपरेट नहीं कर सकते → एक्सटेंशन पैरामीटर्स को अनदेखा करें जब तक कि कोई ज्ञात सुरक्षा बाधा विफल न हो।
- पार्स विफलता के बाद किसी फीचर को सक्षम करना → ट्रंकेशन या मध्यवर्ती हेरफेर एक आकस्मिक प्रयोग या विशेषाधिकार में बदल सकता है → एक सुरक्षित डिफ़ॉल्ट पर वापस लौटें और एक वर्गीकृत विफलता रिकॉर्ड करें।
- कैश भिन्नता को अनदेखा करना → एक CDN किसी अन्य उपयोगकर्ता के लिए वैयक्तिकृत क्षमताओं का पुन: उपयोग कर सकता है →
Varyसेट करें, निजी कैशिंग का उपयोग करें, या रिस्पॉन्स को कैश न करें।
फॉलो-अप प्रश्न और उत्तर
फॉलो-अप 1: इसे रिस्पॉन्स JSON में क्यों न रखें?
JSON तब बेहतर हो सकता है जब क्षमता केवल बॉडी में व्यावसायिक डेटा हो। Structured Fields तब उपयोगी होते हैं जब HTTP मेटाडेटा, गेटवे और कैश नीति को बॉडी का उपभोग करने से पहले मान का निरीक्षण करने की आवश्यकता होती है। दोनों अभ्यावेदन (representations) को स्वतंत्र अधिकार न दें; यदि दोनों मौजूद हैं, तो प्राथमिकता परिभाषित करें और असहमति का पता लगाएं।
फॉलो-अप 2: क्या होगा यदि कई प्रॉक्सी फ़ील्ड को संयोजित करते हैं?
निर्दिष्ट करें कि क्या दोहराई गई लाइनें मान्य हैं और उन्हें एक विश्वसनीय सीमा पर एक एकल पार्सर इनपुट में सामान्यीकृत करें। Dictionary के लिए, डुप्लिकेट कुंजियों को अस्वीकार करें या एक स्पष्ट विरोध नियम परिभाषित करें; जो भी मान अंतिम होता है उस पर निर्भर न रहें। एकीकरण परीक्षणों में HTTP/1.1 दोहराई गई लाइनें, HTTP/2 फ़ील्ड प्रतिनिधित्व और वास्तविक CDN पथ शामिल होना चाहिए।
फॉलो-अप 3: क्या होगा यदि किसी नए पैरामीटर को गैर-ASCII टेक्स्ट की आवश्यकता हो?
चुने गए व्याकरण द्वारा सीमित String प्रकार में सीधे UTF-8 न रखें। एक समर्थित Display String एक्सटेंशन को परिभाषित और सत्यापित करें, या डिस्प्ले टेक्स्ट को बॉडी में रखें और फ़ील्ड में एक स्थिर पहचानकर्ता ले जाएं। प्रत्येक मध्यवर्ती और SDK द्वारा प्रकार का समर्थन करने के बाद ही इसे सक्षम करें।
फॉलो-अप 4: पार्सर CPU स्पाइक का कारण बनता है। आप क्या करेंगे?
तुरंत बाइट, सदस्य, नेस्टिंग और पैरामीटर-संख्या सीमाओं को सख्त करें और सीमा से अधिक फ़ील्ड्स को अनुपस्थित मानें। निदान के लिए एक इनपुट हैश और विफलता श्रेणी रखें, पूरा मान नहीं। पार्सिंग को एक सीमित वर्कर में ले जाने से प्रभाव का दायरा (blast radius) कम हो सकता है, लेकिन यह व्याकरण सीमाओं और कैनरी रोलबैक का स्थान नहीं ले सकता।