REST

2013-06-13 8 views
29

के साथ एकाधिक आइटम्स को हटाने के लिए दो चरण दृष्टिकोण का उपयोग क्यों करें हम सभी जानते हैं कि आरईएसटी के माध्यम से एक ही आइटम को हटाने का 'मानक' तरीका एक यूआरआई example.com/Items/666 को एक एकल डिलीट अनुरोध भेजना है। ग्रैंड, चलो एक बार में कई को हटाने के लिए आगे बढ़ते हैं। चूंकि हमें परमाणु हटाने (या सही लेनदेन, यानी सभी या कुछ भी नहीं) की आवश्यकता नहीं है, हम केवल ग्राहक की कठिन किस्मत बता सकते हैं, कई अनुरोध कर सकते हैं 'लेकिन यह बहुत अच्छा नहीं है। इसलिए हमें एक क्लाइंट को कई 'आइटम' को एक बार में हटाने का अनुरोध करने की अनुमति देने की आवश्यकता है।REST

मेरी समझ से, इस समस्या का 'सामान्य' समाधान एक 'दो कदम' दृष्टिकोण है। सबसे पहले ग्राहक आइटम आईडी की एक सूची पोस्ट करता है और example.com/Items/Collection/1 जैसे यूआरआई को वापस कर दिया जाता है। एक बार यह संग्रह बनने के बाद, वे इसे हटा दें।

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

मेरी राय में, एक बेहतर समाधान बस example.com/Items (या शायद example.com/Items/Collection यह सूचित करते हैं कि यह एक से अधिक हटाएं है) और पारित JSON आईडी है कि आप को नष्ट करना चाहते की सूची से युक्त डेटा पर DELETE कॉल करने के लिए किया जाएगा। जहां तक ​​मैं देख सकता हूं, यह मूल रूप से पहली विधि की सभी समस्याओं को हल करता है। क्लाइंट के रूप में उपयोग करना आसान है, सर्वर को जो काम करना है, वह कम कर देता है, वास्तव में स्टेटलेस है, और अधिक अर्थपूर्ण है।

मैं वास्तव में इस पर फ़ीड की सराहना करता हूं, क्या मुझे आरईएसटी के बारे में कुछ याद आ रहा है जो इस समस्या का मेरा समाधान अवास्तविक बनाता है? मैं लेखों के लिंक की भी सराहना करता हूं, खासकर यदि वे इन दो तरीकों की तुलना करते हैं; मुझे पता है कि यह सामान्य रूप से एसओ के लिए अनुमोदित नहीं है। मुझे यह स्वीकार करने में सक्षम होना चाहिए कि केवल पहली विधि वास्तव में RESTfull है, साबित करें कि दूसरा दृष्टिकोण एक व्यवहार्य समाधान है। बेशक, अगर मैं गलत पेड़ को भड़क रहा हूं तो मुझे बताओ।

उत्तर

24

मैंने पिछले सप्ताह बिताया है या फिर आरईएसटी पर एक उचित बिट पढ़ा है, और मेरी समझ के अनुसार, इन समाधानों में से किसी एक को 'रीस्टफुल' के रूप में वर्णित करना गलत होगा, बल्कि आपको यह कहना चाहिए कि 'न तो समाधान आरईएसटी का मतलब क्या है '।

संक्षिप्त उत्तर यह है कि आरईएसटी, जैसा कि Roy Fielding's dissertation में देखा गया है (अध्याय 5 देखें), आरईएसटी मैनेजर में संसाधनों, एकवचन या एकाधिक को हटाने के विषय को शामिल नहीं करता है। यह सही है, संसाधन को हटाने के लिए कोई सही सही तरीका नहीं है ... अच्छा, बिल्कुल नहीं।

आरईएसटी खुद को परिभाषित नहीं करता है कि संसाधन को कैसे हटाया जाए, लेकिन यह परिभाषित करता है कि आप किस प्रोटोकॉल का उपयोग कर रहे हैं (याद रखें कि आरईएसटी प्रोटोकॉल नहीं है) यह क्रियाओं को कैसे कार्यान्वित करेगा। प्रोटोकॉल आमतौर पर HTTP हो जाएगा; फ़ील्डिंग will point out, आरईएसटी के रूप में मुख्य शब्द होने पर 'आमतौर पर' HTTP का पर्याय नहीं है।

तो हम यह कहने के लिए HTTP देखें कि कौन सी विधि 'सही' है। अफसोस की बात है, जहां तक ​​HTTP का संबंध है, दोनों दृष्टिकोण व्यवहार्य हैं। हां 'व्यवहार्य'। HTTP क्लाइंट को एक पेलोड (संग्रह संसाधन बनाने के लिए) के साथ एक POST अनुरोध भेजने की अनुमति देगा, और उसके बाद संसाधनों को हटाने के लिए इस नए संग्रह पर एक DELETE विधि कॉल करें; यह संसाधनों की सूची को हटाने के लिए आपको एक एकल DELETE विधि के पेलोड के भीतर डेटा भेजने की अनुमति देगा।HTTP केवल वह माध्यम है जिसके द्वारा आप सर्वर को अनुरोध भेजते हैं, यह उचित रूप से प्रतिक्रिया देने के लिए सर्वर पर होगा। मेरे लिए, HTTP प्रोटोकॉल स्थानों में व्याख्या के लिए खुले प्रतीत होता है, लेकिन ऐसा लगता है कि क्रियाओं का क्या अर्थ है, उन्हें किस तरह से निपटाया जाना चाहिए और किस प्रतिक्रिया को दी जानी चाहिए; यह सिर्फ 'आपको यह करना चाहिए' की बजाय 'आपको यह करना चाहिए', लेकिन शायद मैं इस शब्द पर थोड़ा पैडेंटिक हूं।

कुछ लोग तर्क देंगे कि 'दो चरण' दृष्टिकोण संभवतः 'आरईएसटी' नहीं हो सकता है क्योंकि सर्वर को दूसरी कार्रवाई करने के लिए क्लाइंट के लिए 'राज्य' स्टोर करना होता है। यह बस कुछ हिस्से की गलतफहमी है। यह समझा जाना चाहिए कि न तो ग्राहक और न ही सर्वर पोस्ट किए जा रहे सूची के बीच किसी अन्य के बारे में 'राज्य' जानकारी संग्रहीत कर रहा है और उसके बाद DELETED हो रहा है। हां, सूची को हटाए जाने से पहले बनाया जाना चाहिए, लेकिन सर्वर को याद नहीं है कि यह क्लाइंट अल्फा था जिसने यह सूची बनाई थी (इस तरह का एक दृष्टिकोण क्लाइंट को अगले अनुरोध के रूप में 'DELETE' को कॉल करने की अनुमति देगा और सर्वर याद करता है उस सूची का उपयोग करने के लिए, यह बिल्कुल स्टेटलेस नहीं होगा) इस प्रकार, क्लाइंट को उस विशिष्ट सूची को हटाने के लिए सर्वर को बताना होगा, जिस सूची को इसे एक विशिष्ट यूआरआई दिया गया था। यदि ग्राहक ने एक संग्रह सूची को हटाने का प्रयास किया जो पहले से मौजूद नहीं था, तो उसे केवल 'संसाधन नहीं मिला' (क्लासिक 404 त्रुटि सबसे अधिक संभावना) बताया जाएगा। यदि आप दावा करना चाहते हैं कि यह दो कदम दृष्टिकोण एक राज्य को बनाए रखता है, तो आपको यह भी दावा करना होगा कि एक यूआरआई प्राप्त करने के लिए एक राज्य की आवश्यकता है, क्योंकि यूआरआई पहले मौजूद होना चाहिए। यह दावा करने के लिए कि 'राज्य' का अर्थ यह है कि 'राज्य' का क्या अर्थ है गलतफहमी है। और आगे 'सबूत' के रूप में कि इस तरह के दो चरण दृष्टिकोण वास्तव में स्टेटलेस है, आप आसानी से ग्राहक अल्फा पोस्ट सूची और बाद में ग्राहक बीटा (अन्य क्लाइंट के साथ कोई संचार किए बिना) सूची संसाधनों पर DELETE कॉल कर सकते हैं।

मुझे लगता है कि यह स्पष्ट रूप से स्पष्ट हो सकता है कि दूसरा विकल्प, DELETE अनुरोध के पेलोड में सूची भेजने का दूसरा विकल्प स्टेटलेस है। अनुरोध को पूरा करने के लिए आवश्यक सभी जानकारी पूरी तरह से एक अनुरोध के भीतर संग्रहीत की जाती है।

यह तर्क दिया जा सकता है कि DELETE कार्रवाई को केवल 'मूर्त' संसाधन पर ही बुलाया जाना चाहिए, लेकिन ऐसा करने में आप आरईएसटी के प्रतिनिधि भाग को स्पष्ट रूप से अनदेखा कर रहे हैं; यह नाम में है! यह प्रतिनिधित्व करने वाला पहलू है जो http://example.com/myService/timeNow जैसे यूआरआई को अनुमति देता है, एक यूआरआई कि जब 'मिल' वापस आ जाएगा, गतिशील रूप से, वर्तमान समय, कुछ फाइल लोड करने या कुछ डेटाबेस से पढ़ने के साथ। यह एक महत्वपूर्ण अवधारणा है कि यूआरआई डेटा के कुछ 'मूर्त' टुकड़े पर सीधे मानचित्रण नहीं कर रहे हैं।

हालांकि उस स्टेटलेस प्रकृति का एक पहलू है जिस पर सवाल किया जाना चाहिए। फील्डिंग का वर्णन अनुभाग 5.1.3 में 'क्लाइंट-राज्यविहीन-सर्वर' के रूप में, वह कहता है:

We next add a constraint to the client-server interaction: communication must 
    be stateless in nature, as in the client-stateless-server (CSS) style of 
    Section 3.4.3 (Figure 5-3), such that each request from client to server must 
    contain all of the information necessary to understand the request, and 
    cannot take advantage of any stored context on the server. Session state is 
    therefore kept entirely on the client. 

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

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

तो मैं एक प्रश्न पर, एक ही प्रश्न के साथ अपने प्रश्न का उत्तर दे रहा हूं, 'आप दो कदम दृष्टिकोण क्यों मानेंगे?'

+2

मुझे नहीं लगता कि आरईएसटी का बिंदु यह है कि सर्वर के पास ** कोई ** राज्य नहीं हो सकता है (उदाहरण के लिए, सर्वर पर * कुछ * सर्वर पर आईडी को मैप करने के लिए राज्य की आवश्यकता है), लेकिन वह इसमें कोई * प्रति सत्र * राज्य नहीं है। इस प्रकार, या तो विधि शायद योग्यता प्राप्त करती है, हालांकि मैं मानता हूं कि एक कदम दृष्टिकोण अभी भी बेहतर है। –

+0

आप निष्कर्ष पर कैसे आते हैं कि एक चरण दृष्टिकोण में प्रति सत्र राज्य शामिल है? मैंने सोचा कि मैंने यह स्पष्ट कर दिया है कि न तो दृष्टिकोण को एक सत्र सत्र की आवश्यकता होगी, जैसे शॉपिंग कार्ट की तरह कुछ अक्सर उपयोग किया जाता है। – thecoshman

+0

मैं इस तरह के किसी निष्कर्ष पर नहीं आया - मैंने अभी निष्कर्ष निकाला है कि दो-चरणीय दृष्टिकोण में शामिल "राज्य" आरईएसटी के विचारों का उल्लंघन नहीं करता है। –

2

IMO:

HTTP मौजूदा संग्रह पर DELETE अपने सदस्य को हटाना ठीक लग रहा है। सभी सदस्यों को अजीब लगता है हटाने के लिए संग्रह बनाना। जैसा कि आप स्वयं सुझाव देते हैं, जेएसओएन (या कोई अन्य पेलोड प्रारूप) का उपयोग करके हटाए गए आइटमों को बस पास करें। मुझे लगता है कि सर्वर को कई लेन-देन को आंतरिक लेनदेन करने की कोशिश करनी चाहिए।

+0

जहां तक ​​आप जानते हैं, उनके किसी भी * तकनीकी * कारण है कि आप इस तरह के एक डेली अनुरोध के शरीर में एक पेलोड क्यों नहीं भेज सकते हैं? मैंने HTTP spec के बारे में क्या पढ़ा है; सभी अनुरोध विधियों, जब तक कि अन्यथा न कहा गया हो, संदेश संदेश हो सकता है, और DELETE अनुरोध अन्यथा नहीं कहता है। हालांकि नाइट पिकर्स को फिर से खाली करने के लिए, हाँ यह एक 'इकाई' – thecoshman

+0

है, मुझे DELETE में पेलोड के साथ किसी भी समस्या से अवगत नहीं है। हम इसे DELETE और GET (पूछो नहीं) विधियों में उपयोग कर रहे हैं। – wilx

+0

(जो वास्तव में समझ में आता है)। देखें, मैं एक इंटरफेस से निपटने जा रहा हूं जहां आप थोक कार्यों को भेजना चाहते हैं; एक बार में सैकड़ों बनाता है, हटा देता है, अपडेट करता है। यह आंतरिक तंत्र के लिए नीचे है जिसका अर्थ है कि हम एक समय में तेजी से प्रक्रिया कर सकते हैं। उत्सुक, आप * यह कैसे प्राप्त करेंगे? क्या आप इन दो दृष्टिकोणों को दूर करने वाले किसी भी संसाधन के बारे में जानते हैं? मेरे लिए यह अपेक्षाकृत सरल लगता है, सिग्नल अनुरोध का उपयोग करना आसान है, और सर्वर को चीजों के बारे में चिंता करने की बचत करता है जैसे कि यह सूचियां कितनी देर तक रखती हैं। – thecoshman

1

मैं तर्क दूंगा कि HTTP पहले से हीpersistent connections and pipelining के रूप में एकाधिक आइटम हटाने का तरीका प्रदान करता है। HTTP प्रोटोकॉल स्तर पर idppotent विधियों का अनुरोध करने के लिए बिल्कुल ठीक है जैसे कि एक पाइपलाइन तरीके से DELETE - यानी, एक ही कनेक्शन पर एक बार में सभी DELETE अनुरोध भेजें और सभी प्रतिक्रियाओं का इंतजार करें।

ब्राउज़र में चल रहे AJAX क्लाइंट के लिए यह समस्याग्रस्त हो सकता है क्योंकि कुछ ब्राउज़रों में डिफ़ॉल्ट रूप से पाइपलाइनिंग समर्थन सक्षम होता है। यह HTTP की गलती नहीं है, हालांकि, यह उन विशिष्ट ग्राहकों की गलती है।

+0

यह प्रभावी रूप से 'लगातार' पाइप के माध्यम से किए गए एकाधिक एकल डिलीट अनुरोध है। तो यह सचमुच सिर्फ एक काम है (और यह बुरा नहीं है) इस तथ्य को संभालने के लिए कि, मूल रूप से, HTTP प्रति संसाधन एक संसाधन पर काम करता है। – thecoshman