2009-04-12 11 views
14

मैंने हाल ही में HTTP 1.1 विनिर्देश पढ़ने और इसे आरईएसटी से संबंधित बहुत समय बिताया है। मैंने पाया है कि इसकी "बेवकूफता" और सुरक्षा के संबंध में HTTP DELETE विधि की दो व्याख्याएं हैं। यहाँ दो शिविरों हैं:HTTP DELETE के संदर्भ में idempotency देखने का सही तरीका क्या है?

  1. आप हटाना HTTP के साथ एक संसाधन को हटाते हैं, और यह सफल होता है (200 ठीक), और फिर आप समय की है कि संसाधन एन संख्या को हटाने का प्रयास है, तो आप वापस मिलना चाहिए एक सफलता संदेश (200 ओके) उन सभी में से प्रत्येक के लिए कॉल हटाएं। यह इसकी "बेवकूफता" है।

  2. यदि आप HTTP DELETE के साथ संसाधन हटाते हैं, और यह सफल होता है (200 ठीक है), और फिर आप उस संसाधन को फिर से हटाने का प्रयास करते हैं, तो आपको एक त्रुटि संदेश (410 चला गया) वापस लेना चाहिए क्योंकि संसाधन हटा दिया गया था।

विनिर्देश DELETE कहते हैं, idempotent है यकीन है, लेकिन यह भी कहता है कि idempotent घटनाओं के दृश्यों अभी भी साइड इफेक्ट का उत्पादन कर सकते हैं। मुझे सच में लगता है कि दूसरा शिविर सही है, और पहला भ्रामक है। ग्राहकों को यह सोचने की अनुमति देकर हमने "सुरक्षा" क्या पेश की है कि वे पहले से हटाए गए संसाधन को हटाने का कारण थे?

इस विषय पर कई लेखकों समेत पहले शिविर में बहुत से लोग हैं, इसलिए मैं यह जांचना चाहता था कि भावनाओं के अलावा कुछ अनिवार्य कारण हैं जो लोगों को पहले शिविर में ले जाते हैं।

+0

आपके # 2 के साथ, मुझे लगता है कि आपको "हाल ही में" हटाने की हालियाता को इस प्रतिक्रिया की रणनीति के साथ कुछ भी नहीं करना चाहिए। –

+0

@ जेफमार्टिन आप सही हैं, यह तथ्यात्मक से अधिक बातचीतत्मक था। हटा दिया। –

उत्तर

19

बेवकूफ होने का मतलब यह नहीं है कि अनुरोध को दुष्प्रभाव होने की अनुमति नहीं है (यही वह 'सुरक्षित' संपत्ति वर्णन करता है)। इसका मतलब यह है कि एक ही अनुरोध को कई बार जारी करने से अलग-अलग या अतिरिक्त दुष्प्रभाव नहीं होंगे।

मेरी राय में, बाद में DELETE अनुरोध को एक त्रुटि वापस करनी चाहिए - यह अभी भी बेवकूफ है क्योंकि सर्वर की स्थिति वही है जैसे केवल एक ही अनुरोध अनुरोध किया गया था। फिर फिर से 200 ओके स्थिति को वापस करना ठीक है - मुझे नहीं लगता कि idempotent को के बाद के DELETE अनुरोधों के लिए त्रुटि कोड लौटने की आवश्यकता है - यह केवल त्रुटि स्थिति को वापस करने के लिए मुझे अधिक समझ में आता है।

+0

मेरे पास एक ही राय है, मुझे किसी और को यह साझा करने में खुशी है। मुझे लगता है मुझे बस इसे सुनने की जरूरत है। धन्यवाद। मेरे पास इस विषय पर कुछ किताबें हैं और एक आश्चर्यजनक संख्या बेवकूफता का इलाज कर रही है जैसे कि यह भी सुरक्षित थी, और ऐसा नहीं है। –

+0

एक चेतावनी: मैं शायद ही कभी एक HTTP/REST विशेषज्ञ को बुलाऊंगा ... –

+0

एक विरोधी दृश्य बिंदु के रूप में, मुझे लगता है कि "यह सुनिश्चित करें कि यह संसाधन हटा दिया गया है/हटा दिया गया है" के साथ एक डेली अनुरोध अधिक है। चाहे अनुरोध के समय मौजूद है, वास्तव में प्रतिक्रिया की सफलता की स्थिति से कोई फर्क नहीं पड़ता है। यदि दो अलग-अलग क्लाइंट "एक ही समय में" अनुरोध अनुरोध को क्यों भेजें, तो 1 को त्रुटि प्रतिक्रिया और दूसरी सफलता क्यों मिलनी चाहिए, जब वास्तव में दोनों ने सफलतापूर्वक लक्ष्य पूरा किया। –

2

@MichaelBurr idempotency और दुष्प्रभावों के बारे में सही है।

मेरी राय यह है कि दिए गए आरईएसटी अनुरोध, ग्राहक के राज्य और सर्वर के राज्य में शामिल 2 राज्य हैं। आरईएसटी इन राज्यों को सर्वर और क्लाइंट के बीच स्थानांतरित करने के बारे में है, जैसे क्लाइंट के राज्य मानचित्र सर्वर के राज्य के सबसेट में, दूसरे शब्दों में, सबसेट सर्वर के अनुरूप रहता है। उस बेवकूफता के कारण इसका मतलब यह होना चाहिए कि बाद के बेवकूफ अनुरोधों के परिणामस्वरूप राज्य अलग-अलग नहीं होगा, केवल एक बार अनुरोध करने से ही होगा। पहले डिलीट के साथ आप कल्पना करेंगे कि सर्वर संसाधन को हटा देता है और क्लाइंट को यह जानने देता है कि यह संसाधन को भी हटा सकता है (क्योंकि संसाधन "अब मौजूद नहीं है")। अब दोनों राज्यों को हटाए गए आइटम को घटाकर कम से कम होना चाहिए। क्लाइंट को कुछ भी अलग करने के लिए जब यह आइटम को पहले ही हटा दिया गया है, तो उसे हटाने की कोशिश करता है, तो सर्वर से सर्वर से स्थानांतरित होने वाली स्थिति में अलग-अलग जानकारी होनी चाहिए। सर्वर सूचनाओं के साथ कुछ अलग तरीके से काम कर सकता है कि संसाधन पहले ही हटा दिया गया था, लेकिन एक बार जब यह विधियों के कुछ अलग-अलग idempotency के साथ प्रतिक्रिया करता है तो अनिवार्य रूप से टूटा हुआ है।

idempotent समारोह के लिए:

delete(client_state) -> client_state - {item} 
delete(delete(client_state)) -> client_state - {item} 
delete(client_state) = delete(delete(client_state)) 

इस idempotency गारंटी करने के लिए सबसे अच्छा तरीका है अगर सर्वर की प्रतिक्रिया समान है, कि ग्राहक के राज्य को तोड़ने के लिए idempotency वहाँ के लिए गैर हो रहा है के लिए एक ही रास्ता का मतलब ग्राहक की प्रतिक्रिया के संचालन में निर्धारकता या दुष्प्रभाव (जो शायद प्रतिक्रिया को संभालने के गलत कार्यान्वयन को इंगित करता है)।

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

HTTP अनुरोध तरीकों को दूर करना शामिल है, तो समारोह के समान हो सकता है

delete(client_state) = send_delete(client_state) -> receive_delete(client_state) 
               -> respond_to_delete(informative_state) 
               -> handle_response(informative_state) 
               -> client_state - {item} 
+0

यह एक दिलचस्प तर्क है। मैं अभी भी स्पष्ट नहीं हूं कि कैसे "ठीक" इस असंगतता या मजबूर अस्पष्टता को हल करता है। मैं मानता हूं कि यदि आप एक समान प्रतिक्रिया प्रदान करते हैं, तो आप बेहतर होते हैं, लेकिन अगर हम किसी भी राज्य संक्रमण को तोड़ने का विकल्प नहीं चुनते हैं, तो हम यह नहीं देखते हैं कि "यह संसाधन पहले स्थान पर कभी अस्तित्व में नहीं था, इसलिए आप इसे हटा नहीं सकते" (404) बनाम "यह संसाधन यहां होता था, लेकिन यह अब और नहीं है, इसलिए आपको शायद अपने कैश को फ्लश करना चाहिए" (406) ... –

+1

... आपको हर स्थिति में सर्वर से समान जवाब मिलेंगे यह अपने जीवनकाल के दौरान एक विशिष्ट संसाधन के लिए सच था। ओके के माध्यम से समानता के लिए पूछना सर्वर से पूछताछ के बारे में विवरण छिपाने के लिए सर्वर से पूछता है कि एपीआई के आधार पर अच्छा डिज़ाइन नहीं हो सकता है। मैं इसे और अधिक चबाऊंगा, लेकिन मुझे अभी भी डिलीट 1 पसंद है -> ठीक है, हटाएं 2. एन - एक संसाधन के लिए गया जो कभी बनाया गया था और हटाएं 1. एन 404 बाकी सब कुछ के लिए नहीं मिला। –

+0

@DanielCrenna लेकिन कुछ हटाने का प्रयास करने का अर्थ है कि आपको लगता है कि यह मौजूद है (यानी ग्राहक मानता है कि यह सर्वर पर होना चाहिए)। संसाधनों के लिए कभी भी 404 जीईटी ऑपरेशन के लिए अधिक उचित कोड नहीं बनाया गया है। – tenkod

0

Wikipedia एक ऑपरेशन के रूप में परिभाषित करता है Idempotence:

प्रारंभिक आवेदन परे परिणाम बदले बिना कई बार लागू किया जा सकता।

ध्यान दें कि वे ऑपरेशन के result के बारे में बात करते हैं। मेरे लिए, इसमें दोनों सर्वर राज्य और प्रतिक्रिया कोड शामिल हैं।

HTTP विनिर्देश इस मामले पर थोड़ा अधिक अस्पष्ट है। यह defines it निर्दिष्ट करता है कि HTTP विधियां Idempotent हैं:

यदि एकाधिक समान अनुरोधों का इच्छित प्रभाव एक ही अनुरोध के समान है।

आप विकिपीडिया परिभाषा effectresult के रूप में व्याख्या तो वे एक ही मतलब है। किसी भी मामले में, मैं ग्राहकों को यह बताने के व्यावहारिक लाभ पर सवाल करता हूं कि संसाधन पहले ही हटा दिया गया है।

अंतिम बिंदु: एक ग्राहक के संदर्भ में बेवकूफता परिभाषित की गई है। एक बार जब आप अन्य ग्राहकों द्वारा समवर्ती अनुरोध शुरू करना शुरू कर देते हैं, तो सभी दांव बंद हो जाते हैं। ऐसे मामलों से निपटने के लिए आपको सशर्त-अपडेट हेडर (जैसे If-Match-ETag) का उपयोग करना होगा।

दोहराने के लिए: आपको एक ही रिटर्न कोड वापस करना चाहिए, चाहे संसाधन अभी हटा दिया गया हो, पिछले अनुरोध से हटा दिया गया था, या कभी भी अस्तित्व में नहीं था।

+0

नहीं, यह "प्रभाव" का जवाब भी प्रतिक्रिया को कवर करने का इरादा नहीं है। आप जो प्रस्तावित करते हैं वह है कि या तो हमेशा पास होना चाहिए ("200") या विफल ("404" या "410"), इससे कोई फर्क नहीं पड़ता कि सर्वर की स्थिति क्या है। यह कोई समझ नहीं आता है और इसके अलावा ग्राहक की मदद नहीं करता है। –

+0

@ जुलिएन रेस्के, यदि आप http://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-24#section-4.3 पढ़ते हैं।5 विनिर्देश सभी कानूनी प्रतिक्रियाओं को 'DELETE' में सूचीबद्ध करता है। '404' और' 410' उनमें से एक नहीं हैं। इस प्रकार, कृपया डाउनवोट हटा दें। – Gili

+0

नहीं, विनिर्देश * DELETE को "सभी" कानूनी प्रतिक्रियाओं को सूचीबद्ध नहीं करता है। यह सिर्फ उदाहरण देता है। –

संबंधित मुद्दे