एपीआई संस्करण


9

मान लीजिए कि आपके पास एपीआई आधार द्वारा समर्थित एक बड़ी परियोजना है। यह परियोजना एक सार्वजनिक एपीआई को भी शिप करती है जिसका उपयोग (ईश) उपयोगकर्ता कर सकते हैं।

कभी-कभी आपको एपीआई आधार में बदलाव करने की आवश्यकता होती है जो आपकी परियोजना का समर्थन करता है। उदाहरण के लिए, आपको एक ऐसी सुविधा जोड़ने की आवश्यकता है जिसमें एपीआई परिवर्तन, एक नई विधि या वस्तुओं में से किसी एक को बदलने की आवश्यकता हो, या एपीआई से पारित या उन वस्तुओं में से किसी एक का प्रारूप।

यह मानते हुए कि आप अपने सार्वजनिक एपीआई में इन वस्तुओं का उपयोग कर रहे हैं, सार्वजनिक वस्तुएं आपके द्वारा किए जाने वाले किसी भी समय को बदल देंगी, जो अवांछनीय है क्योंकि आपके ग्राहक एपीआई वस्तुओं पर निर्भर रह सकते हैं जो उनके पार्सिंग कोड के काम करने के लिए समान हैं। (खांसी C ++ WSDL क्लाइंट ...)

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

तो क्या कुछ पवित्रता है जो आमतौर पर इस स्थिति पर लागू होती है? मुझे पता है कि कई सार्वजनिक सेवाएं जैसे कि Git for Windows एक संस्करणित API बनाए रखता है, लेकिन मुझे एक ऐसे आर्किटेक्चर की कल्पना करने में परेशानी हो रही है जो विभिन्न संस्करण विधियों और इनपुट / आउटपुट ऑब्जेक्ट्स को कवर करने वाले भारी मात्रा में डुप्लिकेट कोड के बिना इसका समर्थन करता है।

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


1
I don't see a good way to do that without duplicating code- आपका नया एपीआई हमेशा आपके पुराने एपीआई, या इसके विपरीत तरीकों को कॉल कर सकता है।
रॉबर्ट हार्वे

2
बचाव के लिए AutoMapper, दुर्भाग्य से हाँ- आपको प्रत्येक अनुबंध के अलग-अलग संस्करणों की आवश्यकता है, यह मत भूलो कि आपके अनुबंध द्वारा संदर्भित सभी ऑब्जेक्ट उस अनुबंध का एक हिस्सा हैं। परिणाम यह है कि आपका वास्तविक कार्यान्वयन मॉडल का अपना एकल संस्करण होना चाहिए, और आपको एकल संस्करण को विभिन्न अनुबंध संस्करणों में बदलना होगा। AutoMapper कॉन्ट्रैक्ट मॉडल की तुलना में आंतरिक मॉडल को स्मार्ट बनाने में आपकी मदद कर सकता है। AutoMapper की अनुपस्थिति में, मैंने आंतरिक मॉडल और अनुबंध मॉडल के बीच सरल अनुवाद बनाने के लिए विस्तार विधियों का उपयोग किया है।
जिमी होफा

क्या इसके लिए कोई विशिष्ट मंच / संदर्भ है? (यानी, DLL's, एक REST API, आदि)
ग्रैंडमास्टरबी

.NET, MVC और Webforms ui, dll वर्गों के साथ। हमारे पास आराम और साबुन एपीआई दोनों हैं।
केस

जवाबों:


6

जब एक एपीआई बनाए रखा जाता है जो तीसरे पक्ष द्वारा उपयोग किया जाता है तो यह अपरिहार्य है कि आपको बदलाव करने की आवश्यकता होगी। जटिलता का स्तर परिवर्तन के प्रकार पर निर्भर करेगा जो कि घट रहा है। ये मुख्य परिदृश्य हैं जो सामने आते हैं:

  1. मौजूदा एपीआई के लिए नई कार्यक्षमता जोड़ा गया
  2. एपीआई से पुरानी कार्यक्षमता
  3. मौजूदा परिवर्तनशीलता किसी तरह एपीआई में बदल रही है

मौजूदा एपीआई में नई कार्यक्षमता जोड़ना

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

एपीआई से पुरानी कार्यक्षमता

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

मौजूदा परिवर्तनशीलता किसी तरह एपीआई में बदल रही है

यह परिदृश्य परिवर्तन के प्रकार पर निर्भर करेगा। यदि इनपुट मापदंडों का अब उपयोग करने की आवश्यकता नहीं है, तो आप अभी के अतिरिक्त डेटा को अनदेखा करने के लिए सेवा / लाइब्रेरी को अपडेट कर सकते हैं। एक पुस्तकालय में यह अतिभारित पद्धति को आंतरिक रूप से नई पद्धति को कॉल करना होगा जिसमें कम मापदंडों की आवश्यकता होती है। एक होस्ट की गई सेवा में आपके पास समापन बिंदु अतिरिक्त डेटा को अनदेखा करता है और यह दोनों प्रकार के ग्राहकों की सेवा कर सकता है और एक ही तर्क को चला सकता है।

यदि मौजूदा कार्यक्षमता के लिए नए आवश्यक तत्वों को जोड़ना है तो आपके पास अपनी सेवा / लाइब्रेरी के लिए दो समापन बिंदु / तरीके होने चाहिए। जब तक ग्राहक अपडेट नहीं करते तब तक आपको दोनों संस्करणों का समर्थन करने की आवश्यकता है।

अन्य विचार

Rather, the API is likely to extend the private objects we are using for our base API, but then we run into the same problem because added properties would also be available in the public API when they are not supposed to be.

अपने पुस्तकालय / सेवा के माध्यम से आंतरिक निजी वस्तुओं को उजागर न करें। अपने स्वयं के प्रकार बनाएं और आंतरिक कार्यान्वयन को मैप करें। यह आपको आंतरिक परिवर्तन करने और बाहरी ग्राहकों को अपडेट करने की मात्रा को कम करने की अनुमति देगा।

The problem is more that it seems like many or most changes require breaking the public API if the objects aren't more separated, but I don't see a good way to do that without duplicating code.

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

इस चरण को "डुप्लिकेट कोड" के रूप में न देखें। इसी तरह, वे अलग-अलग इकाइयाँ हैं जो बनाने के समय के लायक हैं। जबकि बाहरी एपीआई परिवर्तनों को लगभग हमेशा आंतरिक कार्यान्वयन के लिए एक समान परिवर्तन की आवश्यकता होती है, आंतरिक कार्यान्वयन परिवर्तन हमेशा बाहरी एपीआई को नहीं बदलना चाहिए।

उदाहरण

मान लीजिए आप एक भुगतान प्रसंस्करण समाधान प्रदान कर रहे हैं। आप क्रेडिट कार्ड लेनदेन करने के लिए PaymentProviderA का उपयोग कर रहे हैं। बाद में आपको PaymentProviderB के भुगतान प्रोसेसर के माध्यम से एक बेहतर दर मिलती है। यदि आपके API ने PaymentProviderA के प्रतिनिधित्व के बजाय आपके प्रकार के क्रेडिट कार्ड / बिल एड्रेस फ़ील्ड को उजागर कर दिया है, तो API परिवर्तन 0 है क्योंकि इंटरफ़ेस समान रहा (उम्मीद है कि वैसे भी, अगर PaymentProviderB को ऐसे डेटा की आवश्यकता होती है, जिसे PaymentProviderA की आवश्यकता नहीं थी, तो आपको या तो चुनने की आवश्यकता है दोनों का समर्थन करें या PaymentProviderA के साथ बदतर दर को बनाए रखें)।


इसके लिए बहुत विस्तृत उत्तर के लिए धन्यवाद। क्या आप ओपन सोर्स प्रोजेक्ट्स के किसी भी उदाहरण के बारे में जानते हैं जो मैं यह जानने के लिए मना कर सकता हूं कि मौजूदा परियोजनाओं ने यह कैसे किया है? मैं कुछ ठोस उदाहरण देखना चाहता हूं कि उन्होंने किस प्रकार कोड का आयोजन किया है जो उन्हें अपने विभिन्न POCO निर्माण कोड को विभिन्न संस्करण वस्तुओं में कॉपी किए बिना ऐसा करने की अनुमति देता है, क्योंकि यदि आप साझा किए गए तरीकों को कहते हैं, तो आपको इसे अलग करना होगा। साझा किए गए तरीके को उस ऑब्जेक्ट को संपादित करने में सक्षम होने के लिए।
केस

1
मुझे अपने सिर के ऊपर से किसी भी अच्छे उदाहरण के बारे में पता नहीं है। अगर मेरे पास इस सप्ताह के अंत में कुछ समय है तो मैं GitHub पर फेंकने के लिए एक परीक्षण ऐप बना सकता हूं, यह दिखाने के लिए कि इनमें से कुछ को कैसे लागू किया जा सकता है।
फिल पैटरसन

1
मुश्किल हिस्सा यह है कि उच्च स्तर से ग्राहकों और सर्वरों के बीच युग्मन को कम करने के लिए कई अलग-अलग तरीके हैं। WCF में IExtensibleDataObject नाम का एक इंटरफ़ेस है जो आपको डेटा को क्लाइंट से अनुबंध में नहीं है और इसे तार पर सर्वर को भेजने की अनुमति देता है। Google ने सिस्टम के बीच संचार के लिए प्रोटोबॉफ़ बनाया (.NET, जावा, आदि के लिए खुले स्रोत कार्यान्वयन हैं)। इसके अलावा कई संदेश आधारित प्रणालियाँ हैं जो काम भी कर सकती हैं (यह मानते हुए कि आपकी प्रक्रिया को अतुल्यकालिक रूप से निष्पादित किया जा सकता है)।
फिल पैटरसन

कोड दोहराव का एक विशिष्ट उदाहरण दिखाने के लिए एक बुरा विचार नहीं हो सकता है जिसे आप हटाने की कोशिश कर रहे हैं (एक नए स्टैक ओवरफ्लो प्रश्न के रूप में) और देखें कि समुदाय किन समाधानों के साथ आता है। सामान्य शब्दों में प्रश्न का उत्तर देना मुश्किल है; इसलिए एक विशिष्ट परिदृश्य बेहतर हो सकता है।
फिल पैटरसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.