अनुरोध अनुरोध निकाय के लिए प्रतिष्ठित विकल्प


93

जबकि HTTP 1.1 कल्पना करने लगता है की अनुमति देते हैं पर संदेश निकायों DELETE अनुरोध है, यह संकेत मिलता है कि सर्वर इसे अनदेखा चाहिए, क्योंकि इसके लिए कोई परिभाषित अर्थ विज्ञान हैं लगता है।

4.3 संदेश निकाय

एक सर्वर किसी भी अनुरोध पर संदेश-निकाय को पढ़ता और अग्रेषित करता है; यदि अनुरोध पद्धति में निकाय-निकाय के लिए परिभाषित शब्दार्थ शामिल नहीं हैं, तो अनुरोध को संभालते समय संदेश-निकाय SHOULD को अनदेखा किया जाना चाहिए।

मैंने पहले ही इस विषय पर SO और उसके बाद के कई संबंधित चर्चाओं की समीक्षा की है, जैसे:

अधिकांश चर्चाओं से लगता है कि DELETE पर एक संदेश निकाय प्रदान करने की अनुमति दी जा सकती है , लेकिन आमतौर पर इसकी अनुशंसा नहीं की जाती है।

इसके अलावा, मैंने विभिन्न HTTP क्लाइंट पुस्तकालयों में एक प्रवृत्ति देखी है जहां अधिक से अधिक संवर्द्धन इन पुस्तकालयों के लिए DELETE पर अनुरोध निकायों का समर्थन करने के लिए लॉग इन हो रहे हैं। अधिकांश पुस्तकालयों को उपकृत करना प्रतीत होता है, हालांकि कभी-कभी प्रारंभिक प्रतिरोध का थोड़ा सा साथ।

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

  • संदेश निकाय - यह संकेत इंगित करता है कि DELETE पर संदेश निकायों का कोई शब्दार्थ मूल्य नहीं है; HTTP क्लाइंट द्वारा पूरी तरह से समर्थित नहीं; मानक अभ्यास नहीं
  • कस्टम HTTP हेडर - कस्टम हेडर की आवश्यकता आम तौर पर मानक प्रथाओं के खिलाफ होती है ; उनका उपयोग करना मेरे बाकी एपीआई के साथ असंगत है, जिनमें से किसी को भी कस्टम हेडर की आवश्यकता नहीं है; इसके अलावा, खराब कस्टम हेडर मानों (संभवतः एक अलग प्रश्न) को इंगित करने के लिए कोई अच्छा HTTP प्रतिक्रिया उपलब्ध नहीं है
  • मानक HTTP हेडर - कोई मानक हेडर उपयुक्त नहीं हैं
  • क्वेरी पैरामीटर्स - क्वेरी पैराम्स को जोड़ने से वास्तव में अनुरोध-यूआरआई को हटा दिया जाता है; मानक प्रथाओं के खिलाफ
  • POST विधि - (उदाहरण के लिए POST /resourceToDelete { deletemetadata }) POST हटाने का शब्दार्थ विकल्प नहीं है; पोस्ट वास्तव में प्रतिनिधित्व विपरीत कार्रवाई वांछित (यानी पोस्ट संसाधन मातहत बनाता है, लेकिन मैं संसाधन हटाने की आवश्यकता)
  • मल्टीपल मेथड्स - DELETE अनुरोध को दो ऑपरेशनों में विभाजित करना (जैसे PUT डिलीट मेटाडेटा, फिर DELETE) एक परमाणु ऑपरेशन को दो में विभाजित करता है, संभवतः एक असंगत स्थिति को छोड़कर। हटाने का कारण (और अन्य संबंधित मेटाडेटा) संसाधन प्रतिनिधित्व का हिस्सा नहीं हैं।

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

DELETE अनुरोधों पर इस तरह के आवश्यक मेटाडेटा को शामिल करने के लिए REST / HTTP मानकों के साथ कोई सिफारिशें या सर्वोत्तम अभ्यास सम्मिलित हैं? क्या कोई अन्य विकल्प है जिस पर मैंने विचार नहीं किया है?


2
कुछ कार्यान्वयन जैसे अनुरोधों के Jerseyलिए निकाय को अनुमति नहीं देते deleteहैं।
तुलसीजाम

जवाबों:


44

DELETE अनुरोधों के लिए संदेश निकाय का उपयोग न करने की कुछ सिफारिशों के बावजूद, यह दृष्टिकोण कुछ उपयोग मामलों में उचित हो सकता है। यह वह दृष्टिकोण है जिसका उपयोग हमने प्रश्न / उत्तर में वर्णित अन्य विकल्पों के मूल्यांकन के बाद और सेवा के उपभोक्ताओं के साथ सहयोग करने के बाद किया है।

जबकि संदेश निकाय का उपयोग आदर्श नहीं है, अन्य विकल्पों में से कोई भी पूरी तरह से उपयुक्त नहीं था। अनुरोध निकाय DELETE ने हमें अतिरिक्त डेटा / मेटाडेटा के आसपास आसानी से और स्पष्ट रूप से शब्दार्थ जोड़ने की अनुमति दी, जो DELETE ऑपरेशन के साथ करने के लिए आवश्यक था।

मैं अभी भी अन्य विचारों और चर्चाओं के लिए खुला हूँ, लेकिन इस प्रश्न पर पाश को बंद करना चाहता था। मैं इस विषय पर सभी के विचारों और चर्चाओं की सराहना करता हूं!


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

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

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

मैं इस पर @Quarkly के साथ हूं। मुझे समझ में नहीं आ रहा है कि RESTFUL का क्या विचार है कि हमें कैसे कंसेप्ट चेक करना चाहिए आदि कंसीडर चेक क्लाइंट पर नहीं है।
डर्क वेसल्स

13

आप जो चाहते हैं, वह दो चीजों में से एक है, जिनमें से एक भी शुद्ध नहीं है DELETE:

  1. आपके पास दो ऑपरेशन हैं, एक PUTहटाने का कारण DELETEसंसाधन का एक है। हटाए जाने के बाद, संसाधन की सामग्री अब किसी के लिए सुलभ नहीं है। हटाए गए संसाधन में 'कारण' में हाइपरलिंक नहीं हो सकता है। या,
  2. आप एक संसाधन को बदलने के लिए कोशिश कर रहे हैं से state=activeकरने के लिए state=deletedका उपयोग करके DELETEविधि। राज्य = हटाए गए संसाधनों को आपके मुख्य एपीआई द्वारा नजरअंदाज कर दिया जाता है, लेकिन फिर भी किसी व्यवस्थापक या डेटाबेस एक्सेस वाले किसी व्यक्ति के लिए पठनीय हो सकता है। यह अनुमति है - DELETEकिसी संसाधन के लिए बैकिंग डेटा को मिटाना नहीं है, केवल उस URI में उजागर संसाधन को निकालना है।

किसी भी ऑपरेशन जिसके लिए एक DELETEअनुरोध पर एक संदेश निकाय की आवश्यकता होती है , उसे सबसे सामान्य रूप से तोड़ा जा सकता POSTहै, संदेश शरीर के साथ सभी आवश्यक कार्य करने के लिए, और ए DELETE। मुझे HTTP के शब्दार्थ को तोड़ने का कोई कारण नहीं दिखता है।


2
यदि PUTकारण सफल होता है और DELETEसंसाधन विफल हो जाता है तो क्या होगा ? असंगत अवस्था को कैसे रोका जा सकता है?
लाइटमैन

1
@ लाइट पॉट केवल इरादे को निर्दिष्ट करता है। यह एक संबंधित DELETE के बिना मौजूद हो सकता है, जो यह दर्शाता है कि कोई व्यक्ति हटाना चाहता था लेकिन या तो यह विफल हो गया या उन्होंने अपने दिमाग को बदल दिया। कॉल के क्रम को उलट देना भी DELETE को एक कारण के बिना हो सकता है - एक कारण का प्रावधान तब केवल एनोटेशन माना जाएगा। यह इन दोनों कारणों से है कि मैं ऊपर से विकल्प 2 का उपयोग करने की सिफारिश करूंगा, अर्थात अंतर्निहित रिकॉर्ड की स्थिति को बदलना जैसे HTTP संसाधन को वर्तमान URL से गायब करने का कारण होगा। एक कचरा संग्रहकर्ता / प्रशासक तब अभिलेखों को शुद्ध कर सकता है
निकोलस शैंक्स

7

आपके पास की स्थिति को देखते हुए, मैं निम्नलिखित में से एक तरीका अपनाऊंगा:

  • PUT या PATCH भेजें : मैं यह मान रहा हूं कि डिलीट ऑपरेशन आभासी है, डिलीट कारण की आवश्यकता के कारण। इसलिए, मेरा मानना ​​है कि PUT / PATCH ऑपरेशन के माध्यम से रिकॉर्ड को अपडेट करना एक मान्य दृष्टिकोण है, भले ही यह किसी भी तरह से DELETE ऑपरेशन नहीं है।
  • क्वेरी पैरामीटर का उपयोग करें : संसाधन uri को बदला नहीं जा रहा है। मुझे वास्तव में लगता है कि यह भी एक मान्य दृष्टिकोण है। आपके द्वारा जोड़ा गया प्रश्न क्वेरी पैरामीटर गायब होने पर डिलीट की अनुमति नहीं देने के बारे में बात कर रहा था। आपके मामले में, मेरे पास एक डिफ़ॉल्ट कारण होगा यदि क्वेरी स्ट्रिंग में कारण निर्दिष्ट नहीं है। संसाधन अभी भी हो जाएगा resource/:id। आप प्रत्येक कारण के लिए संसाधन पर लिंक हेडर के साथ इसे खोज योग्य बना सकते हैं (कारण की relपहचान करने के लिए प्रत्येक पर एक टैग के साथ )।
  • प्रति कारण एक अलग समापन बिंदु का उपयोग करें : एक यूआरएल का उपयोग करना resource/:id/canceled। यह वास्तव में अनुरोध-URI को बदल देता है और निश्चित रूप से RESTful नहीं है। फिर से, लिंक हेडर यह खोज कर सकते हैं।

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


क्वेरी परम के उपयोग के बारे में, मेरी समझ यह है कि क्वेरी अनुरोध-URI प्रति खंड 3.2 का हिस्सा है , और इसलिए इस दृष्टिकोण (या इसी तरह, अलग-अलग समापन बिंदु) का उपयोग करते हुए DELETE विधि की परिभाषा के खिलाफ जाता है , जैसे कि - संसाधन अनुरोध द्वारा पहचाना गया- URI "हटा दिया गया है।
शेली

उरई मार्ग से संसाधन की पहचान की जाती है। तो एक GET /orders/:idउसी संसाधन के रूप में लौटाएगा /orders/:id?exclude=orderdetails। क्वेरी स्ट्रिंग केवल सर्वर को संकेत दे रही है - इस मामले में प्रतिक्रिया (यदि समर्थित है) में आदेश दाताओं को बाहर करने के लिए। इसी तरह, यदि आप DELETE को /orders/:idया /orders/:id?reason=canceledउसके पास भेज रहे हैं, तो आप /orders/:id?reason=bad_creditअभी भी उसी अंतर्निहित संसाधन पर काम कर रहे हैं। 'एकसमान इंटरफ़ेस' रखने के लिए, मेरे पास एक डिफ़ॉल्ट कारण होगा ताकि क्वेरी परम को भेजने की आवश्यकता न हो।
कोडप्रोग्रेसियन

@shelley आप क्वेरी स्ट्रिंग के बारे में अपनी चिंताओं में सही हैं। क्वेरी स्ट्रिंग URI का हिस्सा है। एक DELETE अनुरोध भेजने का /foo?123अर्थ है कि आप एक अलग संसाधन हटा रहे हैं यदि आप DELETE को भेजना चाहते थे /foo?456
निकोलस शैंक्स

@codeprogression क्षमा करें, लेकिन आप जो कहते हैं उसमें से बहुत कुछ गलत है। संसाधन की पहचान पूरे यूआरआई द्वारा की जाती है, न कि केवल पथ से। विभिन्न क्वेरी स्ट्रिंग अलग संसाधन (शब्द 'संसाधन' के HTTP अर्थ में) हैं। साथ ही, एक समान इंटरफ़ेस के लिए डिफ़ॉल्ट कारण की आवश्यकता नहीं है। यह शब्द GET, PUT, POST, PATCH और DELETE का उपयोग करने के लिए संदर्भित करता है जिस तरह से वे HTTP परिभाषित करते हैं। समानता विक्रेताओं (उपयोगकर्ता एजेंट विक्रेताओं, एपीआई विक्रेताओं, प्रॉक्सी विक्रेताओं, आईएसपी आदि) को कैच करने के बीच है, न कि किसी के स्वयं के एपीआई के भीतर (हालांकि वह भी उपयोगकर्ताओं की पवित्रता के लिए डिजाइन में एकरूप होना चाहिए!)।
निकोलस शैंक्स

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

0

मेरा सुझाव है कि आप यूआरआई पदानुक्रम के हिस्से के रूप में आवश्यक मेटाडेटा शामिल करें। एक उदाहरण (Naive):

यदि आपको बॉडी में स्टार्ट डेट और एंड डेट या क्वेरी पैरामीटर के रूप में डेट रेंज के आधार पर प्रविष्टियों को हटाने की आवश्यकता है, तो यूआरआई को इस तरह से स्ट्रक्चर करें कि आप यूआरआई के हिस्से के रूप में आवश्यक जानकारी पास करें।

जैसे

DELETE /entries/range/01012012/31122012 - 01 जनवरी 2012 से 31 दिसंबर 2012 के बीच की सभी प्रविष्टियाँ हटा दें

उम्मीद है की यह मदद करेगा।


5
विलोपन के लिए कारण भेजने जैसे मामलों को कवर नहीं करता है यानी कमिटमेंट फील्ड।
कुगेल

3
वाह। एक भयानक विचार है। यदि आपके पास बहुत अधिक मेटा डेटा है, तो यह URI पर आकार प्रतिबंधों को बढ़ा देगा।
बालाजी बोगाराम रामनारायण

1
यह दृष्टिकोण Restful प्रथाओं का पालन नहीं करता है और अनुशंसित नहीं है क्योंकि आपके पास एक जटिल URI संरचना होगी। एंडपॉइंट इंटरटेस्टेड रिसोर्स आइडेंटिफिकेशन बनाम मेटा डेटा से मैड हो जाते हैं और समय के साथ आपके एपीआई में बदलाव के साथ मेंटेनेंस बुरा सपना बन जाएगा। rangeक्वेरी पार्म या पेलोड में निर्दिष्ट होना अधिक पसंद है जो इस प्रश्न का मांस है: समस्या के लिए सर्वोत्तम प्रथाओं के दृष्टिकोण को समझने के लिए जो मैं कहूंगा कि यह नहीं है।
digitaldreamer

@digitaldreamer - मुझे समझ में नहीं आ रहा है कि आप यूआरआई की संरचना से क्या मतलब है? इसके अलावा, यह एक HTTP DELETE है, इसलिए पेलोड एक विकल्प नहीं है, लेकिन क्वेरी पैरामीटर हाँ है।
सुरेश कुमार
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.