हम सभी को चमकदार नए उपकरण पसंद हैं लेकिन उन्हें लगातार अपडेट करने की झंझट से नफरत है। यह किसी भी चीज़ पर लागू होता है: ऑपरेटिंग सिस्टम, ऐप्स, एपीआई, लिनक्स पैकेज। यह दर्दनाक होता है जब हमारा कोड किसी अपडेट के कारण काम करना बंद कर देता है और यह दोगुना दर्द होता है जब अपडेट हमारे द्वारा शुरू भी नहीं किया गया था।
वेब एपीआई विकास में, आपको हर नए अपडेट के साथ अपने उपयोगकर्ताओं के कोड को तोड़ने का लगातार खतरा रहता है। यदि आपका उत्पाद एक एपीआई है, तो ये अपडेट हर बार भयावह होंगे। मोनाइट के मुख्य उत्पाद हमारे एपीआई और हमारे व्हाइट-लेबल एसडीके हैं। हम एक एपीआई-प्रथम कंपनी हैं इसलिए हम अपने एपीआई को स्थिर और उपयोग में आसान बनाए रखने का बहुत ध्यान रखते हैं। इसलिए परिवर्तनों को तोड़ने की समस्या हमारी प्राथमिकता सूची में सबसे ऊपर है।
एक सामान्य समाधान यह है कि आप अपने ग्राहकों को बहिष्कार की चेतावनी जारी करें और कभी-कभार ही ब्रेकिंग परिवर्तन जारी करें। अचानक, आपकी रिलीज़ में अब महीनों लग सकते हैं और कुछ सुविधाओं को प्रत्येक अगली रिलीज़ तक छिपा रहना होगा या यहां तक कि असंबद्ध भी रहना होगा। यह आपके विकास को धीमा कर देता है और आपके उपयोगकर्ताओं को हर कुछ महीनों में अपने एकीकरण को अपडेट करने के लिए मजबूर करता है।
यदि आप तेज़ी से रिलीज़ करते हैं, तो आपके उपयोगकर्ताओं को अपने एकीकरण को बहुत बार अपडेट करना होगा। यदि आप रिलीज़ के बीच का समय बढ़ाते हैं, तो एक कंपनी के रूप में आप धीमी गति से आगे बढ़ेंगे। आप इसे उपयोगकर्ताओं के लिए जितना अधिक असुविधाजनक बनाएंगे - यह आपके लिए उतना ही अधिक सुविधाजनक होगा, और इसके विपरीत भी। यह निश्चित रूप से एक इष्टतम परिदृश्य नहीं है. हम मौजूदा ग्राहकों के लिए कुछ भी तोड़े बिना अपनी गति से आगे बढ़ना चाहते थे जो कि नियमित प्रतिशोध दृष्टिकोण के साथ असंभव होगा। यही कारण है कि हमने एक वैकल्पिक समाधान चुना: एपीआई वर्जनिंग।
यह काफी सरल विचार है: किसी भी समय किसी भी परिवर्तन को जारी करें लेकिन उन्हें एक नए एपीआई संस्करण के तहत छुपाएं। यह आपको दोनों दुनियाओं का सर्वश्रेष्ठ प्रदान करता है: उपयोगकर्ताओं का एकीकरण नियमित रूप से नहीं टूटेगा और आप अपनी पसंद की किसी भी गति से आगे बढ़ने में सक्षम होंगे। उपयोगकर्ता जब चाहें तब स्थानांतरित हो जाएंगे -- किसी भी दबाव से मुक्त।
विचार की सरलता को ध्यान में रखते हुए, यह किसी भी कंपनी के लिए एकदम सही लगता है। आप एक सामान्य इंजीनियरिंग ब्लॉग में यही पढ़ने की उम्मीद करेंगे। अफसोस की बात है, यह इतना आसान नहीं है।
एपीआई संस्करण बनाना कठिन है, बहुत कठिन है। एक बार जब आप इसे लागू करना शुरू करते हैं तो इसकी भ्रामक सादगी जल्दी ही ख़त्म हो जाती है। अफसोस की बात है कि इंटरनेट वास्तव में आपको कभी चेतावनी नहीं देता क्योंकि इस विषय पर आश्चर्यजनक रूप से बहुत कम संसाधन हैं। उनमें से अधिकांश इस बात पर बहस करते हैं कि एपीआई संस्करण को कहां रखा जाए, लेकिन केवल कुछ दुर्लभ लेख ही उत्तर देने का प्रयास करते हैं: "हम इसे कैसे कार्यान्वित करें?"। सबसे आम हैं:
अलग-अलग परिनियोजन वास्तव में महंगे हो सकते हैं और समर्थन करना कठिन हो सकता है, एकल मार्गों की प्रतिलिपि बनाना बड़े परिवर्तनों के लिए बहुत अच्छा नहीं है, और पूरे एप्लिकेशन की प्रतिलिपि बनाने से इतना अतिरिक्त कोड बन जाता है कि आप कुछ संस्करणों के बाद ही इसमें डूबना शुरू कर देंगे।
यहां तक कि अगर आप सबसे सस्ता चुनने की कोशिश करते हैं, तो वर्जनिंग का बोझ जल्द ही बढ़ जाएगा। सबसे पहले, यह सरल लगेगा: यहां एक और स्कीमा जोड़ें, वहां व्यावसायिक तर्क में एक और शाखा जोड़ें, और अंत में कुछ मार्गों की नकल करें। लेकिन पर्याप्त संस्करण दिए जाने पर आपका व्यावसायिक तर्क जल्दी ही असहनीय हो जाएगा, आपके कई डेवलपर एप्लिकेशन संस्करणों और एपीआई संस्करणों में गलती करेंगे, और आपके डेटाबेस के भीतर डेटा का संस्करण बनाना शुरू कर देंगे, और आपके एप्लिकेशन को बनाए रखना असंभव हो जाएगा।
आप उम्मीद कर सकते हैं कि आपके पास एक ही समय में कभी भी दो या तीन से अधिक एपीआई संस्करण नहीं होंगे; कि आप हर कुछ महीनों में पुराने संस्करण हटा सकेंगे। यह सच है यदि आप केवल थोड़ी संख्या में आंतरिक उपभोक्ताओं का समर्थन करते हैं। लेकिन आपके संगठन से बाहर के ग्राहकों को हर कुछ महीनों में अपग्रेड करने के लिए मजबूर किए जाने के अनुभव का आनंद नहीं मिलेगा।
एपीआई संस्करण आपके बुनियादी ढांचे के सबसे महंगे हिस्सों में से एक बन सकता है, इसलिए पहले से ही मेहनती शोध करना महत्वपूर्ण है। यदि आप केवल आंतरिक उपभोक्ताओं का समर्थन करते हैं, तो आपके पास ग्राफक्यूएल जैसी किसी चीज़ के साथ आसान समय हो सकता है, लेकिन यह जल्दी ही वर्जनिंग जितना महंगा हो सकता है।
यदि आप एक स्टार्टअप हैं, तो एपीआई संस्करण को अपने विकास के बाद के चरणों तक स्थगित करना बुद्धिमानी होगी जब आपके पास इसे सही तरीके से करने के लिए संसाधन हों। तब तक, निंदा और अतिरिक्त परिवर्तन रणनीति पर्याप्त हो सकती है। आपका एपीआई हमेशा अच्छा नहीं दिखेगा लेकिन कम से कम आप स्पष्ट संस्करण से बचकर बहुत सारा पैसा बचा लेंगे।
कुछ परीक्षणों और कई त्रुटियों के बाद हम चौराहे पर थे: हमारे पूर्व संस्करण दृष्टिकोण जिनका हमने ऊपर उल्लेख किया था, उन्हें बनाए रखना बहुत महंगा था। हमारे संघर्षों के परिणामस्वरूप, मैंने आवश्यकताओं की निम्नलिखित सूची तैयार की जो एक आदर्श संस्करण ढांचे के लिए आवश्यक होगी:
अफसोस की बात है कि हमारे मौजूदा तरीकों का कोई विकल्प नहीं था। तभी मेरे दिमाग में एक पागलपन भरा विचार आया: क्या होगा अगर हम कुछ परिष्कृत, काम के लिए एकदम सही कुछ बनाने की कोशिश करें - स्ट्राइप के एपीआई संस्करण जैसा कुछ?
अनगिनत प्रयोगों के परिणामस्वरूप, अब हमारे पास कैडविन है: एक ओपन-सोर्स एपीआई वर्जनिंग फ्रेमवर्क जो न केवल स्ट्राइप के दृष्टिकोण को लागू करता है बल्कि इसके शीर्ष पर महत्वपूर्ण रूप से निर्माण करता है। हम इसके फास्टापी और पाइडेंटिक कार्यान्वयन के बारे में बात करेंगे लेकिन मूल सिद्धांत भाषा और रूपरेखा अज्ञेयवादी हैं।
अन्य सभी संस्करणीकरण दृष्टिकोणों की समस्या यह है कि हम बहुत अधिक नकल कर रहे हैं। जब हमारे अनुबंध का केवल एक छोटा सा हिस्सा टूटा तो हम पूरे रूट, नियंत्रक या यहां तक कि एप्लिकेशन की नकल क्यों करेंगे?
कैडविन के साथ, जब भी एपीआई अनुरक्षकों को एक नया संस्करण बनाने की आवश्यकता होती है, तो वे अपने नवीनतम स्कीमा, मॉडल और व्यावसायिक तर्क में ब्रेकिंग परिवर्तन लागू करते हैं। फिर वे एक संस्करण परिवर्तन बनाते हैं - एक वर्ग जो नए संस्करण और पिछले संस्करण के बीच सभी अंतरों को समाहित करता है।
उदाहरण के लिए, मान लें कि पहले हमारे ग्राहक एक पते के साथ एक उपयोगकर्ता बना सकते थे, लेकिन अब हम उन्हें एक के बजाय कई पते निर्दिष्ट करने की अनुमति देना चाहेंगे। संस्करण परिवर्तन इस तरह दिखेगा:
class ChangeUserAddressToAList(VersionChange): description = ( "Renamed `User.address` to `User.addresses` and " "changed its type to an array of strings" ) instructions_to_migrate_to_previous_version = ( schema(User).field("addresses").didnt_exist, schema(User).field("address").existed_as(type=str), ) @convert_request_to_next_version_for(UserCreateRequest) def change_address_to_multiple_items(request): request.body["addresses"] = [request.body.pop("address")] @convert_response_to_previous_version_for(UserResource) def change_addresses_to_single_item(response): response.body["address"] = response.body.pop("addresses")[0]
instructions_to_migrate_to_previous_version का उपयोग कैडविन द्वारा स्कीमा के पुराने एपीआई संस्करणों के लिए कोड उत्पन्न करने के लिए किया जाता है और दो कनवर्टर फ़ंक्शन वह चाल है जो हमें जितने चाहें उतने संस्करण बनाए रखने की अनुमति देती है। प्रक्रिया निम्नलिखित की तरह दिखती है:
हमारे एपीआई अनुरक्षकों द्वारा संस्करण परिवर्तन तैयार करने के बाद, उन्हें कैडविन को यह बताने के लिए इसे हमारे वर्जनबंडल में जोड़ना होगा कि यह वर्जनचेंज कुछ संस्करण में शामिल किया जाएगा:
VersionBundle( Version( date(2023, 4, 27), ChangeUserAddressToAList ), Version( date(2023, 4, 12), CollapseUserAvatarInfoIntoAnID, MakeUserSurnameRequired, ), Version(date(2023, 3, 15)), )
बस इतना ही: हमने एक महत्वपूर्ण बदलाव जोड़ा है लेकिन हमारा व्यावसायिक तर्क केवल एक ही संस्करण को संभालता है - नवीनतम। हमारे द्वारा दर्जनों एपीआई संस्करण जोड़ने के बाद भी, हमारा व्यावसायिक तर्क अभी भी संस्करण तर्क, निरंतर नाम बदलने, अगर और डेटा कनवर्टर्स से मुक्त रहेगा।
संस्करण परिवर्तन एपीआई के सार्वजनिक इंटरफ़ेस पर निर्भर होते हैं और हम मौजूदा एपीआई संस्करणों में लगभग कभी भी ब्रेकिंग परिवर्तन नहीं जोड़ते हैं। इसका मतलब यह है कि एक बार जब हमने संस्करण जारी कर दिया - तो इसे तोड़ा नहीं जाएगा।
चूंकि संस्करण परिवर्तन संस्करणों के भीतर ब्रेकिंग परिवर्तनों का वर्णन करते हैं और पुराने संस्करणों में कोई ब्रेकिंग परिवर्तन नहीं होते हैं, हम यह सुनिश्चित कर सकते हैं कि हमारे संस्करण परिवर्तन पूरी तरह से अपरिवर्तनीय हैं - उनके पास कभी भी बदलने का कोई कारण नहीं होगा। अपरिवर्तनीय संस्थाओं को बनाए रखना बहुत आसान है बजाय अगर वे व्यावसायिक तर्क का हिस्सा हों क्योंकि यह हमेशा विकसित होती रहती है। संस्करण परिवर्तन भी एक के बाद एक लागू किए जाते हैं - संस्करणों के बीच ट्रांसफार्मर की एक श्रृंखला बनाते हैं जो किसी भी अनुरोध को किसी भी नए संस्करण में और किसी भी प्रतिक्रिया को किसी भी पुराने संस्करण में स्थानांतरित कर सकते हैं।
एपीआई अनुबंध केवल स्कीमा और फ़ील्ड की तुलना में कहीं अधिक जटिल हैं। इनमें सभी समापन बिंदु, स्थिति कोड, त्रुटियां, त्रुटि संदेश और यहां तक कि व्यावसायिक तर्क व्यवहार भी शामिल हैं। कैडविन उसी डीएसएल का उपयोग करता है जिसका वर्णन हमने एंडपॉइंट और स्टेटस कोड को संभालने के लिए ऊपर किया है, लेकिन त्रुटियां और व्यावसायिक तर्क व्यवहार एक अलग कहानी है: डीएसएल का उपयोग करके उनका वर्णन करना असंभव है, उन्हें व्यावसायिक तर्क में एम्बेड करने की आवश्यकता है।
इससे ऐसे संस्करण परिवर्तनों को बनाए रखना अन्य सभी की तुलना में अधिक महंगा हो जाता है क्योंकि वे व्यावसायिक तर्क को प्रभावित करते हैं। हम इस संपत्ति को "दुष्प्रभाव" कहते हैं और हम उनके रखरखाव के बोझ के कारण हर कीमत पर उनसे बचने की कोशिश करते हैं। सभी संस्करण परिवर्तन जो व्यावसायिक तर्क को संशोधित करना चाहते हैं, उन्हें साइड इफेक्ट के रूप में चिह्नित करने की आवश्यकता होगी। यह यह जानने का एक तरीका होगा कि कौन से संस्करण में परिवर्तन "खतरनाक" हैं:
class RequireCompanyAttachedForPayment(VersionChangeWithSideEffects): description = ( "User must now have a company_id in their account " "if they want to make new payments" )
यह एपीआई अनुरक्षकों को यह जांचने की भी अनुमति देगा कि क्लाइंट अनुरोध एक एपीआई संस्करण का उपयोग करता है जिसमें यह दुष्प्रभाव शामिल है:
if RequireCompanyToBeAttachedForPayment.is_applied: validate_company_id_is_attached(user)
कैडविन के कई फायदे हैं: यह हमारे डेवलपर्स पर बोझ को काफी कम करता है और स्वचालित रूप से चेंजलॉग उत्पन्न करने और हमारे एपीआई दस्तावेज़ों को बेहतर बनाने के लिए इसे हमारे बुनियादी ढांचे में एकीकृत किया जा सकता है।
हालाँकि, वर्जनिंग का बोझ अभी भी मौजूद है और यहां तक कि एक परिष्कृत ढांचा भी कोई आसान काम नहीं है। हम पूरी कोशिश करते हैं कि एपीआई संस्करण का उपयोग केवल तभी करें जब अत्यंत आवश्यक हो। हम एक विशेष "एपीआई परिषद" के माध्यम से अपने एपीआई को पहले प्रयास में ही सही बनाने का भी प्रयास करते हैं। किसी भी कार्यान्वयन को आगे बढ़ाने से पहले हमारे सर्वश्रेष्ठ डेवलपर्स, परीक्षकों और तकनीकी लेखकों द्वारा सभी महत्वपूर्ण एपीआई परिवर्तनों की समीक्षा की जाती है।
स्ट्राइप पर उनके एपीआई संस्करण लेख के लिए ब्रैंडुर लीच को विशेष धन्यवाद और जब मैंने कैडविन को लागू किया तो उन्होंने मुझे जो मदद दी, उसके लिए यह उनकी मदद के बिना संभव नहीं होगा।
अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।
Copyright© 2022 湘ICP备2022001581号-3