2013-05-22 9 views
6

का उपयोग कर REST Api कार्यान्वयन RESTFUL एपीआई एप्लिकेशन लिखने के सर्वोत्तम प्रथाओं में से एक, संस्करण जोड़ने के लिए है। उदाहरण के लिए:वसंत

http://my-server/api/v1/getData 
http://my-server/api/v2/getData 

हमारा आवेदन वसंत ढांचे का उपयोग करके आरईएसटी एपीआई का खुलासा करता है। हम एक वर्ग को नियंत्रक के रूप में चिह्नित करते हैं, किसी फ़ंक्शन में URL को मैप करने के लिए RequestMapping एनोटेशन का उपयोग करते हैं, और जेसन ऑब्जेक्ट्स से अनुवादित कुछ ऑब्जेक्ट्स को जोड़ते हैं।

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

@RequestMapping(method = RequestMethod.POST, value = "/api/v1/getData") 
public @ResponseBody ResponseDataDTO getData(@RequestBody OperationsDetailsTDO details) {...} 

अब, हम एपीआई के दूसरे संस्करण उपलब्ध कराना चाहते हैं। लगभग 2/3 कार्य समान रहते हैं, और 1/3 बदल रहे हैं। परिवर्तन तर्क और JSON ऑब्जेक्ट दोनों में हैं।

मुझे आश्चर्य है कि कोड को कैसे डिज़ाइन किया जाए। मुझे लगता है कि कोड के इस प्रकार का प्रबंधन करने के लिए कठिन है:

@RequestMapping(method = RequestMethod.POST, value = "/api/{version-var}/getData") 
public @ResponseBody ResponseDataDTO createReleaseFromTemplate(@PathVariable("version-var") Integer version, @RequestBody OperationsDetailsTDO details) { 
if (version == 1) 
{ 
    doForVersion1(); 
} 
else if (version == 2) 
{ 
    doForVersion2(); 
} 

} 

यह, प्रबंधन, क्योंकि हर समारोह में अलग-अलग शाखाओं में हो जाएगा मुश्किल हो जाएगा। बस समस्या का प्रदर्शन करने के लिए, अगर मेरे पास एक स्वचालित उपकरण है जो दस्तावेज उत्पन्न करता है - यह समझने में सक्षम नहीं होगा कि एपीआई क्या है।

दूसरा, मुझे आश्चर्य है कि जेएसओएन ऑब्जेक्ट से जुड़ी कक्षाओं के साथ मुझे क्या करना चाहिए। क्या मुझे मामूली परिवर्तनों के लिए इन सभी वर्गों को डुप्लिकेट करने की ज़रूरत है?

Thx।

+0

संबंधित http://stackoverflow.com/questions/389169/best-practices-for-api-versioning – andyb

+0

यह सब के बाद एक अलग एपीआई है। आपको इसका उपयोग करने वाली कुछ भी बदलनी होगी। –

उत्तर

1

मैं एक पैरामीटर के रूप संस्करण में उत्तीर्ण होने पर आपसे सहमत हूँ, जैसे

@RequestMapping(method = RequestMethod.POST, value = "/api/{version-var}/getData") 

लेकिन मैं इसे शाखाओं के बहुत सारे जोड़ने के लिए एक अच्छा विचार है, हम संसाधन कक्षा में सभी तरीकों को निकालने चाहिए नहीं लगता कि जैसे,

private IDataRetrieve dataRetriever; 
@RequestMapping(method = RequestMethod.POST, value = "/api/{version-var}/getData") 
public @ResponseBody ResponseDataDTO createReleaseFromTemplate(@PathVariable("version-var") Integer version, @RequestBody OperationsDetailsTDO details) { 
    dataRetiever = DataRetrieverFactory.getDataTrieverByVersion(version); //TODO, create a factory to get DataRetriever 
    return dataRetiever.getData(); 
} 

और फिर एक व्यवसाय इंटरफ़ेस, करने के लिए आप IDataRetriver, (V1 के लिए एक, वी 2 के लिए एक और) लागू करने के लिए दो वर्गीकृत की जरूरत है; कारण, डुप्लिकेट कोड से बचने के लिए, आप V1 और V2 के लिए एक सारणी कक्षा जोड़ सकते हैं, और डुप्लिकेट कोड को हटाने के लिए टेम्पलेट पैटरन का उपयोग कर सकते हैं।

+0

+1 मैं केवल इंटरफेस के लिए 'I' उपसर्ग का इतना शौक नहीं हूं। एक ग्राहक को यह नहीं पता होना चाहिए कि यह एक इंटरफ़ेस या कार्यान्वयन का उपयोग कर रहा है। – Bart

+0

और JSON ऑब्जेक्ट्स के बारे में क्या? वे प्रासंगिक वर्गों के अनुसार स्वचालित रूप से जेनरेट होते हैं। क्या मुझे इन कक्षाओं को डुप्लिकेट करने की ज़रूरत है? – Jonathan

+0

मुझे नहीं लगता कि हमें इन कक्षाओं को डुप्लिकेट करना होगा। ("इन कक्षाओं" का अर्थ प्रवेश/दृश्य कक्षाएं है, है ना?)। जैसा कि मैंने सोचा था, v1/v2 में कुछ व्यावसायिक तर्क शामिल होंगे, वापसी समान होनी चाहिए। यदि v1 कुछ विधि का समर्थन नहीं करता है, तो बस अपवाद फेंक दें। – Stony

0

यदि आप संस्करण (see here for example) के लिए पथ चर का उपयोग करते हैं तो आप अपने अनुरोध मैपिंग में नियमित अभिव्यक्तियों का उपयोग कर सकते हैं। या, आप एक नई विधि बना सकते हैं जो बस पुराने को कॉल करे लेकिन वी 2 के लिए नया अनुरोध मैपिंग हो। या, एक सामान्य विधि बनाएं जो संस्करण को पकड़ लेती है और उचित विधि को कॉल करती है जो वास्तविक रूप से अनुरोध के उस संस्करण को संभालती है। अंतिम विधि के लिए बोनस: आप संस्करण को पकड़ सकते हैं और उपयोगकर्ता को एक विशिष्ट त्रुटि पर भेज सकते हैं यदि वे जो संस्करण भेजते हैं वह समर्थित नहीं है, उदाहरण के लिए यदि वे/app/v10/जो भी भेजते हैं।

+0

** ए) ** नियमित अभिव्यक्तियों की कोई आवश्यकता नहीं है। तो इसका इस्तेमाल क्यों करें? ** बी) ** एपीआई संस्करणों की संख्या बढ़ने पर पूरे स्थान पर डुप्लिकेटिंग कोड बहुत प्रबंधनीय नहीं होगा। ** सी) ** आप बस एक संस्करण को दूसरे के लिए डंप नहीं कर सकते हैं। ग्राहक उन एपीआई का उपयोग कर रहे हैं। – Bart

+0

ए) रेगेक्स का उपयोग अनुरोध यूआरएल से मेल खाने में सहायता के लिए किया जा सकता है। यही वह था जो ओपी के लिए पूछ रहा था बी) कोई भी कोड डुप्लिकेट करने के लिए कहा था। वह बूढ़े को छोड़कर एक नया एपीआई बना रहा है। वह नया कोड होगा, है ना? मुझे नहीं लगता कि मैंने जो भी उल्लेख किया है उसे "डुप्लिकेट कोड" की आवश्यकता होगी और सी) कोई भी v1 को डंप नहीं करता है।मैंने कहा "आप रेगेक्स का उपयोग कर सकते हैं या आपके नियंत्रक में v2 के लिए एक और तरीका हो सकता है या आप अपना संस्करण पथ var में बदल सकते हैं, फिर एक विधि है जो" – CodeChimp

+0

अनुरोध किए गए संस्करण के लिए सही अंतर्निहित विधि पर स्विच करती है, वैसे, मेरा मानना ​​है कि आखिरी में मैंने जो सुझाव दिया था वह वही था जो @ सोंटीज़हांग ने सुझाव दिया था, जो संस्करण को एक चर चर के रूप में उपयोग करने के लिए उपयोग करता है यह निर्धारित करने के लिए कि कौन सा संस्करण कॉल करना है। मैंने माना था कि ओपी मानक ओओपी और एमवीसी प्रथाओं का उपयोग कर रहा था, और एक "सेवा परत" कहीं कहीं होगी। – CodeChimp