वस्तुओं का एक गुच्छा हटाने के लिए आराम करने का तरीका


98

में बाकी के लिए विकी लेख यह इंगित किया गया है कि यदि आप का उपयोग http://example.com/resources हटाते हैं तो उस का मतलब है आप पूरे संग्रह हटा रहे हैं।

यदि आप http://example.com/resources/7HOU57Y DELETE का उपयोग करते हैं , तो इसका मतलब है कि आप उस तत्व को हटा रहे हैं।

मैं एक वेबसाइट कर रहा हूँ, नोट नहीं वेब सेवा।

मेरे पास एक सूची है जिसमें सूची के प्रत्येक आइटम के लिए 1 चेकबॉक्स है। एक बार जब मैं विलोपन के लिए कई मदों का चयन करता हूं, तो मैं उपयोगकर्ताओं को DELETE चयन नामक एक बटन दबाने की अनुमति देगा। यदि उपयोगकर्ता बटन दबाता है, तो एक js संवाद बॉक्स उपयोगकर्ता को हटाने की पुष्टि करने के लिए पूछेगा। यदि उपयोगकर्ता पुष्टि करता है, तो सभी आइटम हटा दिए गए हैं।

तो मुझे RESTFUL तरीके से कई वस्तुओं को हटाने के लिए कैसे पूरा करना चाहिए?

ध्यान दें, वर्तमान में एक वेबपेज में DELETE के लिए, मैं क्या कर रहा हूं कि मैं POST के साथ FORM टैग का उपयोग कार्रवाई के रूप में करता हूं, लेकिन मूल्य के साथ _method शामिल करें क्योंकि DELETE में यही है जो SO में अन्य लोगों द्वारा वेबपेज पर Restful Delete करने के लिए संकेत दिया गया था


1
क्या यह महत्वपूर्ण है कि इन विलोपों को परमाणु रूप से निष्पादित किया जाए? क्या आप वास्तव में पहले 30 वस्तुओं के विलोपन को उलट देना चाहते हैं, अगर 31 वीं तारीख को हटाया नहीं जा सकता है?
डारेल मिलर

@darrelmiller अच्छा सवाल। मैंने सोचा कि अगर डिलीट को परमाणु रूप से किया जाता है, तो यह कम कुशल होगा। इसलिए मैं DELETE से tablename की ओर झुकाव कर रहा हूँ, जहाँ पर ID ({आईडी की सूची}) है। अगर कोई मुझे इंगित कर सकता है कि क्या यह एक अच्छा विचार है या मुझे सही करता है। कि अच्छी तरह से सराहना की जाएगी। इसके अलावा, अगर पहले 21 वस्तुओं को हटा दिया जाता है, तो मुझे पहले 20 वस्तुओं को हटाने की आवश्यकता नहीं है। फिर से मैं इसकी सराहना करता हूं कि अगर कोई मुझे दृष्टिकोण में अंतर दिखा सकता है जहां मुझे उल्टा करने की आवश्यकता है, जहां मुझे रिवर्स करने की आवश्यकता नहीं है
किम स्टैक

1
नोट: "IN" खंड के लिए सीमाएं हो सकती हैं; उदाहरण के लिए, ओरेकल में आप अधिकतम 1000 आईडी डाल सकते हैं।
लूट

Google का API डिज़ाइन गाइड एक REST API में कस्टम (बैच) संचालन बनाने के लिए एक समाधान प्रदान करता है, मेरा जवाब यहां देखें: stackoverflow.com/a/53264372/2477619
B12Toaster

जवाबों:


54

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

प्रेषक:
http://example.com/resources/

करो ए

आईडी के चयन के साथ POST:
http://example.com/resources/selections

जो, यदि सफल हो, तो इसके साथ जवाब देना चाहिए:

HTTP / 1.1 201 बनाया, और इसके लिए एक हेडर:
http://example.com/resources/selections/DF4XY7

इस पृष्ठ पर फिर आपको एक (जावास्क्रिप्ट) पुष्टिकरण बॉक्स दिखाई देगा, जो यदि आप पुष्टि करते हैं, तो एक अनुरोध करेंगे:

DELETE http://example.com/resources/selections/DF4XY7

जो, यदि सफल हो, तो इसके साथ जवाब देना चाहिए: HTTP / 1.1 200 Ok (या जो भी एक सफल डिलीट के लिए उपयुक्त है)


मुझे यह विचार पसंद है क्योंकि आपको किसी रीडायरेक्ट की आवश्यकता नहीं है। AJAX को शामिल करते हुए आप बिना पृष्ठ छोड़े यह सब कर सकते हैं।
रोजा

इसके बाद DELETE example.com/resources/selections/DF4XY7 , क्या मुझे उदाहरण के लिए पुनः निर्देशित किया जाएगा।
किम स्टैक

7
@fireeyeboy यह दो कदम दृष्टिकोण एक बहु-हटाने के प्रदर्शन का आमतौर पर सुझाव देने का तरीका है, लेकिन क्यों? आप किसी uri जैसे DELETE अनुरोध को सरल क्यों नहीं भेजते हैं http://example.com/resources/selections/और अनुरोध के पेलोड (निकाय) में आप डेटा भेजते हैं कि आप किन वस्तुओं को हटाना चाहते हैं। जहां तक ​​मैं बता सकता हूं, आपको ऐसा करने से रोकने के लिए कुछ भी नहीं है, लेकिन मैं हमेशा "लेकिन यह RESTfull नहीं है" के साथ मिलता है।
Thecoshman

6
DELETE संभावित रूप से HTTP अवसंरचना द्वारा शरीर की अनदेखी कर सकता है: stackoverflow.com/questions/299628/…
ल्यूक पुप्लेट

DELETE में एक शरीर हो सकता है, लेकिन इसके कार्यान्वयन में बहुत सारे लोग अपने शरीर को डिफ़ॉल्ट रूप से मना करते हैं
dmitryvim

54

एक विकल्प "लेनदेन" हटाना है। तो आप एक नए संसाधन की POSTतरह कुछ करने के लिए http://example.com/resources/deletesसंसाधनों की एक सूची से हटा दिया जाएगा। फिर अपने आवेदन में आप सिर्फ डिलीट करते हैं। जब आप पोस्ट करते हैं तो आपको अपने बनाए लेन-देन का एक स्थान वापस करना चाहिए जैसे http://example.com/resources/deletes/DF4XY7,। इस GETपर लेन-देन की स्थिति (पूर्ण या प्रगति में) और / या हटाए जाने वाले संसाधनों की सूची वापस आ सकती है।


2
अपने डेटाबेस के साथ कुछ नहीं करना है। लेन-देन से मेरा मतलब सिर्फ प्रदर्शन करने के लिए संचालन की सूची है। इस मामले में यह हटाए जाने की सूची है। आप जो भी करते हैं वह आपके एप्लिकेशन में एक संसाधन के रूप में एक नई सूची (डिलीट) करता है। आपका वेब एप्लिकेशन उस सूची को संसाधित कर सकता है, जो आप चाहते हैं। उस संसाधन में एक URI उदाहरण है, example.com/resources/deletes/DF4XY7 । इसका मतलब है कि आप उस URI को GET के माध्यम से डिलीट की स्थिति की जांच कर सकते हैं। यह तब आसान होगा जब आपने डिलीट करते समय आपको अमेजन S3 या किसी अन्य CDN से इमेजेज डिलीट करनी थीं और उस ऑपरेशन को पूरा होने में लंबा समय लग सकता है।
रोजा

2
+1 यह एक अच्छा उपाय है। प्रत्येक संसाधन को एक DELETE भेजने के बजाय, @rojoca एक नए प्रकार के संसाधन का एक उदाहरण बनाने का प्रस्ताव करता है जिसका एकमात्र कार्य संसाधनों की सूची को हटा रहा है। उदाहरण के लिए, आपके पास उपयोगकर्ता संसाधनों का एक संग्रह है और आप अपने संग्रह से उपयोगकर्ता बॉब, डेव और एमी को हटाना चाहते हैं, इसलिए आप सृजन मापदंडों के रूप में एक नया डिलीटेशन संसाधन पोस्टिंग बॉब, डेव और एमी बना सकते हैं। विलोपन संसाधन बनाया गया है, और उपयोगकर्ता संग्रह से बॉब, डेव और एमी को हटाने की अतुल्यकालिक प्रक्रिया का प्रतिनिधित्व करता है।
माइक ट्यूनीक्लिफ

1
मुझे क्षमा करें। मुझे अभी भी कुछ मुद्दों को समझने में थोड़ी मुश्किल है। DF4XY7। आप इस तार को कैसे उत्पन्न करते हैं? यह विलोपन संसाधन। क्या मुझे डेटाबेस में कोई डेटा डालने की आवश्यकता है? अगर मैं कुछ सवाल दोहराता हूं तो मैं माफी मांगता हूं। यह मेरे लिए थोड़ा अपरिचित है।
किम स्टैक

1
मुझे लगता है कि DF4XY7 एक जेनरेट की गई अनूठे आईडी है, शायद DB को सेव करने पर जनरेट की गई आईडी का उपयोग करना अधिक स्वाभाविक है, उदाहरण के लिए example.com/resources/deletes/7। मेरा लेवल डिलेटियन मॉडल बनाने और डेटाबेस में सहेजने के लिए होगा, आपके पास असिंक्रोनस प्रक्रिया हो सकती है जो अन्य रिकॉर्ड्स को हटाकर पूर्ण स्थिति, और किसी भी प्रासंगिक त्रुटियों के साथ डिलीट मॉडल अपडेट कर सकती है।
माइक ट्यूनीक्लिफ

2
@rojoca हाँ, मुझे लगता है कि समस्या बहुत अधिक है 'DELETE एक संसाधन को हटाने के लिए है'। आप कभी भी क्या करते हैं, एक से अधिक डिलीट करना हैक का एक सा है। आप ग्राहक को यह कहते हुए भी 'नौकरी' लौटा सकते हैं कि इस कार्य पर काम किया जा रहा है (और इसमें कुछ समय लग सकता है) लेकिन प्रगति की जाँच करने के लिए इस यूआरआई का उपयोग करें। मैंने युक्ति पढ़ी और यह मान लिया कि DELETE में अन्य अनुरोधों की तरह ही एक निकाय हो सकता है।
thecoshman

33

यहाँ अमेज़न ने अपने S3 REST API के साथ क्या किया।

व्यक्तिगत अनुरोध हटाएं:

DELETE /ObjectName HTTP/1.1
Host: BucketName.s3.amazonaws.com
Date: date
Content-Length: length
Authorization: authorization string (see Authenticating Requests (AWS Signature Version 4))

बहु-वस्तु हटाएँ अनुरोध:

POST /?delete HTTP/1.1
Host: bucketname.s3.amazonaws.com
Authorization: authorization string
Content-Length: Size
Content-MD5: MD5

<?xml version="1.0" encoding="UTF-8"?>
<Delete>
    <Quiet>true</Quiet>
    <Object>
         <Key>Key</Key>
         <VersionId>VersionId</VersionId>
    </Object>
    <Object>
         <Key>Key</Key>
    </Object>
    ...
</Delete>           

लेकिन फेसबुक ग्राफ़ एपीआई , पार्स सर्वर रीस्ट एपीआई और Google ड्राइव रीस्ट एपीआई एक अनुरोध में आपको "बैच" व्यक्तिगत संचालन को सक्षम करके और भी आगे जाते हैं।

यहाँ पार्स सर्वर से एक उदाहरण है।

व्यक्तिगत अनुरोध हटाएं:

curl -X DELETE \
  -H "X-Parse-Application-Id: ${APPLICATION_ID}" \
  -H "X-Parse-REST-API-Key: ${REST_API_KEY}" \
  https://api.parse.com/1/classes/GameScore/Ed1nuqPvcm

बैच अनुरोध:

curl -X POST \
  -H "X-Parse-Application-Id: ${APPLICATION_ID}" \
  -H "X-Parse-REST-API-Key: ${REST_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
        "requests": [
          {
            "method": "POST",
            "path": "/1/classes/GameScore",
            "body": {
              "score": 1337,
              "playerName": "Sean Plott"
            }
          },
          {
            "method": "POST",
            "path": "/1/classes/GameScore",
            "body": {
              "score": 1338,
              "playerName": "ZeroCool"
            }
          }
        ]
      }' \
  https://api.parse.com/1/batch

13

मैं कहूंगा कि DELETE http://example.com/resources/id1,id2,id3,id4 या DELETE http://example.com/resources/id1+id2+id3+id4 । जैसा कि इस विकिपीडिया लेख को उद्धृत करने के लिए "REST एक वास्तुकला (...) [नहीं] प्रोटोकॉल" है, मेरा मानना ​​है कि ऐसा करने का कोई एक तरीका नहीं है।

मुझे पता है कि HTML के साथ JS के बिना ऊपर संभव नहीं है, लेकिन मुझे लगता है कि REST था:

  • लेनदेन जैसे मामूली विवरण के बारे में सोचे बिना। किसे और अधिक एकल आइटम पर काम करना होगा? यह HTTP प्रोटोकॉल में किसी भी तरह से न्यायसंगत है क्योंकि इसका उद्देश्य इसके अलावा कुछ और स्थिर वेबपेजों के माध्यम से सेवा करना नहीं था।
  • आवश्यक नहीं कि वर्तमान मॉडल में भी समायोजन हो - शुद्ध HTML का भी।

thx - यदि आप संपूर्ण संग्रह को हटाना चाहते हैं - तो क्या आईडी को छोड़ दिया जाना चाहिए?
BKSpurgeon

"मुझे लगता है कि REST था ... लेन-देन की तरह मामूली विवरण के बिना बनाया गया है" - मुझे नहीं लगता कि यह काफी सच है। अगर मैं सही ढंग से समझता हूं, तो REST में, लेन-देन संसाधनों द्वारा दर्शाए जाते हैं, न कि किसी विधि द्वारा। इस ब्लॉग पोस्ट की इस टिप्पणी में कुछ अच्छी चर्चा है ।
पॉल डी। वेट

10

दिलचस्प है, मुझे लगता है कि एक ही विधि कई संस्थाओं को पाट करने के लिए लागू होती है, और हमें अपने URL, पैरामीटर और REST विधि के साथ क्या मतलब है, इसके बारे में सोचने की आवश्यकता है।

  1. सभी 'फू' तत्वों को वापस करें:

    [GET] api/foo

  2. विशिष्ट आईडी के लिए फ़िल्टरिंग के साथ 'फू' तत्व लौटाएं:

    [GET] api/foo?ids=3,5,9

जिसमें URL और फ़िल्टर यह निर्धारित करते हैं कि "हम किन तत्वों के साथ काम कर रहे हैं?"

  1. इसलिए उन्हें पढ़ने के लिए चिह्नित करने के लिए कई रिकॉर्ड पाटें

    [PATCH] api/foo?ids=3,5,9

.. डेटा फू के साथ [पढ़ें] = 1

  1. अंत में कई रिकॉर्ड हटाने के लिए, यह समापन बिंदु सबसे तार्किक है:

    [DELETE] api/foo?ids=3,5,9

कृपया समझें कि मुझे विश्वास नहीं है कि इस पर कोई "नियम" हैं - मेरे लिए यह सिर्फ "समझ में आता है"


वास्तव में PATCH के बारे में : चूंकि इसका मतलब आंशिक अपडेट से है, यदि आप संस्थाओं की सूची के बारे में खुद को एक इकाई के रूप में सोचते हैं (भले ही प्रकार सरणी), तो एक आंशिक सरणी (केवल आईडी जिसे आप अपडेट करना चाहते हैं) को भेजना है, फिर आप क्वेरी स्ट्रिंग छोड़ सकते हैं, इस प्रकार एक से अधिक इकाई का प्रतिनिधित्व करने वाला URL नहीं है।
शैबॉल्स पाला

2

जैसा कि डिसेंट डब्बलर उत्तर और रोज़ोकाज़ उत्तर कहता है, संसाधनों के चयन को हटाने के लिए सबसे अधिक विहित आभासी संसाधनों का उपयोग कर रहा है, लेकिन मुझे लगता है कि यह एक REST के दृष्टिकोण से गलत है, क्योंकि निष्पादित करने DELETE http://example.com/resources/selections/DF4XY7से चयन संसाधन को हटा देना चाहिए, चयनित संसाधनों को नहीं।

Maciej Piechotka anwser या fezfox उत्तर लेते हुए , मुझे केवल एक आपत्ति है: आईडी का एक सरणी पास करने का एक अधिक विहित तरीका है, और सरणी ऑपरेटर का उपयोग कर रहा है:

DELETE /api/resources?ids[]=1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d&ids[]=7e8f9a0b-1c2d-3e4f-5a6b-7c8d9e0f1a2b

इस तरह आप डिलीट कलेक्शन एंडपॉइंट पर हमला कर रहे हैं लेकिन डिलीट को सही तरीके से क्वेरिस्ट्रिंग से फ़िल्टर कर रहे हैं।


-1

जैसा कि यह करने के लिए कोई 'उचित' तरीका नहीं है, जो मैंने अतीत में किया है:

शरीर में एक्सएमएल या जोंस एनकोडेड डेटा के साथ http://example.com/something को DELETE भेजें ।

जब आप अनुरोध प्राप्त करते हैं, तो DELETE की जांच करें, यदि सही है, तो हटाए जाने के लिए शरीर को पढ़ें।


यह वह दृष्टिकोण है जो मेरे लिए समझ में आता है, आप बस एक अनुरोध में डेटा भेजते हैं, फिर भी मैं हमेशा "लेकिन यह R राइफल नहीं है"। क्या आपको ऐसा कोई स्रोत मिला है जो यह सुझाव दे कि यह करने के लिए एक व्यवहार्य और 'RESTfull' विधि है?
Thecoshman

10
इस दृष्टिकोण के साथ समस्या यह है कि DELETE संचालन एक निकाय की अपेक्षा नहीं करता है, और इसलिए इंटरनेट पर कुछ मध्यवर्ती राउटर आपके नियंत्रण या ज्ञान के बिना इसे आपके लिए निकाल सकते हैं। तो DELETE के लिए बॉडी का उपयोग करना सुरक्षित नहीं है!
एलेक्स व्हाइट

एलेक्स की टिप्पणी का संदर्भ: stackoverflow.com/questions/299628/…
ल्यूक पुप्लेट

1
A payload within a DELETE request message has no defined semantics; sending a payload body on a DELETE request might cause some existing implementations to reject the request.से tools.ietf.org/html/rfc7231#section-4.3.5
Cottton

-1

कई वस्तुओं को हटाने के लिए मेरी यही स्थिति थी। यही मैंने समाप्त किया। मैंने DELETE ऑपरेशन का उपयोग किया और जिन आइटम्स को डिलीट किया जाना था, वे HTTP हेडर का हिस्सा थे।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.