आप संस्करण वाले API के लिए अंतर्निहित कोडबेस का प्रबंधन कैसे करते हैं?


104

मैं रीस्ट एपीआई के लिए संस्करण रणनीतियों पर पढ़ रहा हूं, और उनमें से कुछ भी पता नहीं दिखाई देता है कि आप अंतर्निहित कोडबेस का प्रबंधन कैसे करते हैं।

मान लें कि हम API में परिवर्तन करने का एक गुच्छा बना रहे हैं - उदाहरण के लिए, हमारे ग्राहक संसाधन को बदलना ताकि यह एक फ़ील्ड के बजाय अलग forenameऔर surnameफ़ील्ड लौटाए name। (इस उदाहरण के लिए, मैं URL संस्करण समाधान का उपयोग करूंगा क्योंकि इसमें शामिल अवधारणाओं को समझना आसान है, लेकिन यह प्रश्न सामग्री बातचीत या कस्टम HTTP हेडर पर समान रूप से लागू है)

अब हमारे पास एक समापन बिंदु है http://api.mycompany.com/v1/customers/{id}, और एक और असंगत समापन बिंदु है http://api.mycompany.com/v2/customers/{id}। हम अभी भी v1 एपीआई में बगफिक्स और सुरक्षा अपडेट जारी कर रहे हैं, लेकिन नई सुविधा विकास अब सभी v2 पर ध्यान केंद्रित कर रहा है। हम अपने एपीआई सर्वर में परिवर्तन कैसे लिखते हैं, परीक्षण और तैनाती करते हैं? मैं कम से कम दो समाधान देख सकता हूं:

  • V1 कोडबेस के लिए स्रोत नियंत्रण शाखा / टैग का उपयोग करें। v1 और v2 विकसित किए गए हैं, और स्वतंत्र रूप से तैनात किए गए हैं, संशोधन नियंत्रण मर्ज के रूप में दोनों संस्करणों के लिए एक ही बगफिक्स को लागू करने के लिए आवश्यक है - एक समान नए संस्करण को विकसित करने के दौरान आप मूल एप्लिकेशन के लिए कोडबेस का प्रबंधन कैसे करेंगे, जबकि पिछले संस्करण का समर्थन करते हुए।

  • कोडबेस को एपीआई संस्करणों से ही अवगत कराएं, इसलिए आप एक सिंगल कोडबेस के साथ समाप्त होते हैं जिसमें v1 ग्राहक प्रतिनिधित्व और वी 2 ग्राहक प्रतिनिधित्व शामिल है। वर्जनिंग को अपने सॉल्यूशन आर्किटेक्चर के हिस्से के रूप में तैनाती के मुद्दे के बजाय समझो - शायद नाम स्थान के कुछ संयोजन का उपयोग करना और सुनिश्चित करने के लिए राउटिंग सही संस्करण द्वारा नियंत्रित किया जाता है।

शाखा मॉडल का स्पष्ट लाभ यह है कि पुराने एपीआई संस्करणों को हटाने के लिए यह तुच्छ है - बस उपयुक्त शाखा / टैग को तैनात करना बंद करें - लेकिन यदि आप कई संस्करण चला रहे हैं, तो आप वास्तव में जटिल शाखा संरचना और तैनाती पाइपलाइन के साथ समाप्त हो सकते हैं। "यूनिफ़ाइड कोडबेस" मॉडल इस समस्या से बचा जाता है, लेकिन (मुझे लगता है?) कोडबेस से हटाए गए संसाधनों और समापन बिंदुओं को हटाने के लिए बहुत कठिन बना देगा जब उन्हें अब आवश्यकता नहीं होगी। मुझे पता है कि यह संभवतः व्यक्तिपरक है क्योंकि एक सरल सही उत्तर होने की संभावना नहीं है, लेकिन मैं यह समझने के लिए उत्सुक हूं कि विभिन्न संस्करणों में जटिल एपीआई बनाए रखने वाले संगठन इस समस्या को कैसे हल कर रहे हैं।


41
यह सवाल पूछने के लिए धन्यवाद! मैं नहीं मान सकता कि अधिक लोग इस प्रश्न का उत्तर नहीं दे रहे हैं !! मैं बीमार हूं और हर किसी के बारे में एक राय है कि संस्करण एक प्रणाली में कैसे प्रवेश करते हैं, लेकिन कोई भी अपने उपयुक्त कोड को संस्करणों को भेजने की वास्तविक कठिन समस्या से निपटने के लिए नहीं लगता है। अब तक कम से कम "पैटर्न" या "समाधान" के एक सरणी को कम से कम इस सामान्य समस्या के रूप में होना चाहिए। "एपीआई संस्करण" के बारे में SO पर प्रश्नों की एक पागल संख्या है। संस्करणों को स्वीकार करने का निर्णय लेना FRIKKIN SIMPLE (अपेक्षाकृत) है! एक बार कोडबस में इसे संभालते ही यह हार्ड हो जाता है!
अरिजीत

जवाबों:


45

मैंने आपके द्वारा उल्लिखित दोनों रणनीतियों का उपयोग किया है। उन दो में से, मैं दूसरे दृष्टिकोण का समर्थन करता हूं, जो सरल है, ऐसे मामलों में जो इसका समर्थन करते हैं। यही है, अगर संस्करण की आवश्यकताएं सरल हैं, तो एक सरल सॉफ़्टवेयर डिज़ाइन के साथ जाएं:

  • परिवर्तनों की कम संख्या, कम जटिलता परिवर्तन या कम आवृत्ति परिवर्तन शेड्यूल
  • कोडबेस के बाकी हिस्सों में बड़े पैमाने पर रूढ़िवादी हैं: सार्वजनिक एपीआई "अत्यधिक" की आवश्यकता के बिना बाकी स्टैक के साथ शांति से मौजूद हो सकता है (उस अवधि की जो भी परिभाषा आप अपनाते हैं उसके लिए) कोड में शाखाओं में बँटना।

मुझे इस मॉडल का उपयोग करके हटाए गए संस्करणों को निकालना बहुत मुश्किल नहीं लगा:

  • अच्छा परीक्षण कवरेज का मतलब था कि एक सेवानिवृत्त एपीआई और संबंधित बैकिंग कोड को तेज करना कोई (अच्छी तरह से, न्यूनतम) प्रतिगमन सुनिश्चित करता है
  • अच्छी नामकरण रणनीति (एपीआई-संस्करण पैकेज नाम, या कुछ बदसूरत, विधि नामों में एपीआई संस्करण) ने प्रासंगिक कोड का पता लगाना आसान बना दिया
  • क्रॉस-कटिंग चिंताएं कठिन हैं; कई एपीआई का समर्थन करने के लिए कोर बैकएंड सिस्टम में संशोधन बहुत सावधानी से तौला जाना चाहिए। कुछ बिंदु पर, बैकिंग संस्करण की लागत (ऊपर "अत्यधिक" पर टिप्पणी देखें) एक एकल कोडबेस के लाभ से आगे निकल जाती है।

पहला दृष्टिकोण निश्चित रूप से सह-मौजूदा संस्करणों के बीच संघर्ष को कम करने के दृष्टिकोण से सरल है, लेकिन अलग-अलग प्रणालियों को बनाए रखने के ओवरहेड ने संस्करण संघर्ष को कम करने के लाभ को पछाड़ दिया। उस ने कहा, एक नए सार्वजनिक एपीआई स्टैक को खड़ा करना और एक अलग एपीआई शाखा पर चलना शुरू करना आसान था। बेशक, पीढ़ीगत नुकसान लगभग तुरंत में सेट हो गया, और शाखाएं मर्ज की गड़बड़ी, मर्ज संघर्ष प्रस्तावों और इस तरह के अन्य मज़े में बदल गईं।

एक तीसरा दृष्टिकोण वास्तुशिल्प परत पर है: मुखौटा पैटर्न का एक संस्करण अपनाएं, और अपने एपीआई को सार्वजनिक रूप से सामना करना पड़ रहा है, संस्करण परतें जो उपयुक्त मुखौटा उदाहरण से बात करती हैं, जो बदले में एपीआई के अपने सेट के माध्यम से बैकेंड से बात करती हैं। आपका मुखौटा (मैंने अपने पिछले प्रोजेक्ट में एक एडेप्टर का उपयोग किया) अपना स्वयं का पैकेज, स्व-निहित और परीक्षण योग्य बन जाता है, और आपको बैकएंड के स्वतंत्र रूप से और एक-दूसरे के फ्रंटएंड एपीआई को माइग्रेट करने की अनुमति देता है।

यह काम करेगा यदि आपके एपीआई संस्करण एक ही प्रकार के संसाधनों को उजागर करते हैं, लेकिन विभिन्न संरचनात्मक अभ्यावेदन के साथ, जैसा कि आपके फुलनेम / फोरनेम / सरनेम उदाहरण में। यह थोड़ा कठिन हो जाता है अगर वे अलग-अलग बैकएंड कंप्यूटर्स पर भरोसा करना शुरू कर देते हैं, जैसा कि, "मेरी बैकएंड सेवा ने गलत तरीके से गणना की गई ब्याज की वापसी की है जो सार्वजनिक एपीआई v1 में उजागर हुई है। हमारे ग्राहकों ने पहले ही इस गलत व्यवहार को पैच कर दिया है। इसलिए, मैं अपडेट नहीं कर सकता। बैकएंड में अभिकलन और यह v2 तक लागू होता है। इसलिए अब हमें अपने ब्याज गणना कोड को कांटा करने की आवश्यकता है। " सौभाग्य से, उन लोगों का झुकाव कम होता है: व्यावहारिक रूप से, Restful API के उपभोक्ता बग-फॉर-बग बैकवर्ड संगतता पर सटीक संसाधन अभ्यावेदन का पक्ष लेते हैं, यहाँ तक कि सैद्धांतिक रूप से निष्क्रिय GETटेड संसाधन पर गैर-ब्रेकिंग परिवर्तनों के बीच भी ।

मुझे आपके अंतिम निर्णय को सुनने में दिलचस्पी होगी।


5
स्रोत कोड में बस उत्सुक, क्या आप v0 और v1 के बीच मॉडल की नकल करते हैं जो नहीं बदला? या क्या आपके पास v1 का उपयोग कुछ v0 मॉडल है? मेरे लिए, अगर मैं v1 को कुछ क्षेत्रों के लिए v0 मॉडल का उपयोग करके देखता हूं तो मुझे भ्रम होगा। लेकिन दूसरी ओर, यह कोड ब्लोट को कम करेगा। कई संस्करणों को संभालने के लिए हमें केवल उन मॉडलों के लिए दोहराए गए कोड के साथ स्वीकार करना और जीना है जो कभी नहीं बदले?
एजकेशबर्ग

1
मेरा स्मरण यह है कि हमारे स्रोत कोड ने स्वतंत्र रूप से एपीआई के ही मॉडल का संस्करण बनाया है, इसलिए उदाहरण के लिए एपीआई v1 मॉडल वी 1 का उपयोग कर सकता है, और एपीआई वी 2 भी मॉडल वी 1 का उपयोग कर सकता है। मूल रूप से, सार्वजनिक एपीआई के लिए आंतरिक निर्भरता ग्राफ में दोनों उजागर एपीआई कोड, साथ ही सर्वर और मॉडल कोड जैसे बैकएंड "पूर्ति" कोड शामिल थे। कई संस्करणों के लिए, मैंने केवल एक ही रणनीति का उपयोग किया है पूरे स्टैक का दोहराव - एक हाइब्रिड दृष्टिकोण (मॉड्यूल ए को डुप्लिकेट किया गया है, मॉड्यूल बी को संस्करणित किया गया है ...) बहुत भ्रामक लगता है। YMMV बेशक। :)
पलपेटिम

2
मुझे यकीन नहीं है कि मैं तीसरे दृष्टिकोण के लिए सुझाए गए का पालन करता हूं। क्या कोड के कोई सार्वजनिक उदाहरण हैं जो इसकी तरह संरचित हैं?
एहतेश चौधरी

13

मेरे लिए दूसरा दृष्टिकोण बेहतर है। मैं इसे SOAP वेब सेवाओं के लिए उपयोग करता हूं और REST के लिए भी इसका उपयोग करने की योजना बना रहा हूं।

जैसा कि आप लिखते हैं, कोडबेस को संस्करण से अवगत होना चाहिए, लेकिन एक संगतता परत का उपयोग अलग परत के रूप में किया जा सकता है। आपके उदाहरण में, कोडबेस पहले और अंतिम नाम के साथ संसाधन प्रतिनिधित्व (JSON या XML) का उत्पादन कर सकता है, लेकिन संगतता परत इसे केवल नाम के बजाय बदल देगी।

कोडबेस को केवल नवीनतम संस्करण को लागू करना चाहिए, v3 कहना चाहिए। संगतता परत को नवीनतम संस्करण v3 और समर्थित संस्करणों जैसे v1 और v2 के बीच अनुरोधों और प्रतिक्रिया को बदलना चाहिए। संगतता परत में प्रत्येक समर्थित संस्करण के लिए एक अलग एडेप्टर हो सकता है जिसे चेन के रूप में जोड़ा जा सकता है।

उदाहरण के लिए:

ग्राहक v1 अनुरोध: v1 v2 के लिए अनुकूल ---> v2 v3 के लिए अनुकूल ---- ---- कोडबेस

ग्राहक v2 अनुरोध: v1 v2 के लिए अनुकूल (छोड़ें) ---> v2 v3 के लिए अनुकूल है ----> कोडबेस

प्रतिक्रिया के लिए एडेप्टर विपरीत दिशा में काम करते हैं। यदि आप जावा ईई का उपयोग कर रहे हैं, तो आप उदाहरण के लिए एडेप्टर चेन के रूप में सर्वलेट फ़िल्टर श्रृंखला दे सकते हैं।

एक संस्करण को निकालना आसान है, संबंधित एडाप्टर और परीक्षण कोड को हटा दें।


यदि संपूर्ण अंतर्निहित कोड आधार बदल गया है तो संगतता की गारंटी देना मुश्किल है। बग-फिक्स रिलीज़ के लिए पुराने कोडबेस को बनाए रखने के लिए अधिक सुरक्षित है।
मार्सेलो कैंटोस

5

ब्रांचिंग मेरे लिए बहुत बेहतर है, और मैंने अपने मामले में इस दृष्टिकोण का उपयोग किया।

हाँ जैसा कि आपने पहले ही उल्लेख किया है - बग फिक्सिंग के बैकपोर्ट में कुछ प्रयासों की आवश्यकता होगी, लेकिन एक ही समय में एक स्रोत आधार (रूटिंग और अन्य सभी सामानों के साथ) के तहत कई संस्करणों का समर्थन करने पर आपको कम नहीं बल्कि कम से कम एक ही प्रयास करने की आवश्यकता होगी, जिससे सिस्टम अधिक हो जाता है अंदर तर्क की विभिन्न शाखाओं के साथ जटिल और राक्षसी (निश्चित रूप से संस्करण के कुछ बिंदुओं पर आपको case()कोड मॉड्यूल को कोड डुप्लिकेट, या इससे भी बदतर होने वाले विशाल मॉड्यूल की ओर संकेत मिलेगा if(version == 2) then...)। यह भी मत भूलना कि प्रतिगमन प्रयोजनों के लिए आपको अभी भी परीक्षणों को शाखायुक्त रखना है।

संस्करण नीति के बारे में: मैं वर्तमान से अधिकतम -2 संस्करणों के रूप में रखूंगा, पुराने लोगों के लिए समर्थन को बढ़ाता हूं - जो उपयोगकर्ताओं को स्थानांतरित करने के लिए कुछ प्रेरणा देगा।


मैं इस समय एक ही कोडबेस में परीक्षण के बारे में सोच रहा हूं। आपने उल्लेख किया है कि परीक्षणों को हमेशा शाखाओं में रखने की आवश्यकता होगी लेकिन मैं सोच रहा हूं कि v1, v2, v3 आदि के लिए सभी परीक्षण एक ही समाधान में भी रह सकते हैं और सभी को एक ही समय में चलाया जा सकता है। मैं उन विशेषताओं के साथ परीक्षणों को सजाने के बारे में सोच रहा हूं जो निर्दिष्ट करते हैं कि वे किन संस्करणों का समर्थन करते हैं: उदाहरण [Version(From="v1", To="v2")]के लिए [Version(From="v2", To="v3")], [Version(From="v1")] // All versions बस इसे अब खोज रहे हैं, कभी किसी ने ऐसा करते सुना?
ली गुन

1
खैर, 3 साल बाद मुझे पता चला है कि मूल प्रश्न का कोई सटीक उत्तर नहीं है: डी। यह बहुत परियोजना पर निर्भर है। यदि आप एपीआई को फ्रीज कर सकते हैं और केवल इसे बनाए रख सकते हैं (जैसे बगफिक्स) तो मैं अभी भी संबंधित कोड (एपीआई-संबंधित व्यवसाय तर्क + परीक्षण + बाकी समापन बिंदु) को शाखा / अलग कर दूंगा और सभी साझा सामान को अलग-अलग पुस्तकालय (अपने स्वयं के परीक्षणों के साथ) में रख सकता हूं )। अगर वी 1 काफी समय से वी 2 के साथ सह-अस्तित्व में है और फीचर का काम अभी भी जारी है, तो मैं उन्हें एक साथ रखूँगा और परीक्षण करूँगा (वी 1, वी 2 आदि को कवर करके और तदनुसार नाम दिया गया)।
एडमरिसोव

1
धन्यवाद। हाँ, यह एक काफी जगह माना जाता है। मैं पहले एक समाधान दृष्टिकोण की कोशिश करने जा रहा हूं और देखता हूं कि यह कैसे जाता है।
ली गुन

0

आमतौर पर, एपीआई के एक प्रमुख संस्करण का परिचय आपको कई संस्करणों को बनाए रखने की स्थिति में अग्रणी होता है एक ऐसी घटना है जो अक्सर नहीं होती है (या नहीं होनी चाहिए)। हालाँकि, इसे पूरी तरह से टाला नहीं जा सकता है। मुझे लगता है कि यह कुल मिलाकर एक सुरक्षित धारणा है कि एक प्रमुख संस्करण, एक बार पेश किया गया, अपेक्षाकृत लंबे समय तक नवीनतम संस्करण रहेगा। इसके आधार पर, मैं दोहराव की कीमत पर कोड में सादगी हासिल करना पसंद करूंगा क्योंकि यह मुझे नवीनतम संस्करण में बदलाव लाने पर पिछले संस्करण को नहीं तोड़ने का बेहतर विश्वास देता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.