REST वेब सेवाओं में बैच संचालन से निपटने के लिए पैटर्न?


170

REST शैली वेब सेवा के भीतर संसाधनों पर बैच संचालन के लिए कौन से सिद्ध डिज़ाइन पैटर्न मौजूद हैं?

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

कुछ मामले हैं जहां आप वस्तुओं के एक पूरे सेट के एक क्षेत्र को अद्यतन करना चाहते हैं। किसी एक फ़ील्ड को अपडेट करने के लिए प्रत्येक ऑब्जेक्ट के लिए संपूर्ण प्रतिनिधित्व भेजने के लिए यह बहुत ही बेकार लगता है।

RPC शैली API में, आपके पास एक विधि हो सकती है:

/mail.do?method=markAsRead&messageIds=1,2,3,4... etc. 

यहाँ REST समतुल्य है? या अब और फिर समझौता करना ठीक है। क्या यह कुछ विशिष्ट कार्यों में जोड़ने के लिए डिज़ाइन को बर्बाद करता है जहां यह वास्तव में प्रदर्शन में सुधार करता है, आदि? सभी मामलों में क्लाइंट अभी एक वेब ब्राउज़र है (क्लाइंट साइड पर जावास्क्रिप्ट एप्लिकेशन)।

जवाबों:


77

बैचों के लिए एक सरल Restful पैटर्न एक संग्रह संसाधन का उपयोग करना है। उदाहरण के लिए, एक साथ कई संदेश हटाने के लिए।

DELETE /mail?&id=0&id=1&id=2

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

POST /mail?markAsRead=true
POSTDATA: ids=[0,1,2]

मूल रूप से, आप पढ़ी गई मेल की सूची को अपडेट कर रहे हैं।

आप इसे एक ही श्रेणी में कई आइटम असाइन करने के लिए भी उपयोग कर सकते हैं।

POST /mail?category=junk
POSTDATA: ids=[0,1,2]

आईट्यून्स-स्टाइल बैच आंशिक अपडेट (जैसे, कलाकार + एल्बमटिटेल लेकिन ट्रैकटाइटल नहीं) करने के लिए यह स्पष्ट रूप से बहुत अधिक जटिल है। बाल्टी सादृश्य टूटने लगता है।

POST /mail?markAsRead=true&category=junk
POSTDATA: ids=[0,1,2]

लंबे समय में, एकल आंशिक संसाधन, या संसाधन विशेषताओं को अपडेट करना बहुत आसान है। बस एक सब-सोर्स का उपयोग करें।

POST /mail/0/markAsRead
POSTDATA: true

वैकल्पिक रूप से, आप पैरामीटर किए गए संसाधनों का उपयोग कर सकते हैं। REST पैटर्न में यह कम सामान्य है, लेकिन URI और HTTP स्पेक्स में इसकी अनुमति है। एक अर्धविराम एक संसाधन के भीतर क्षैतिज रूप से संबंधित मापदंडों को विभाजित करता है।

कई विशेषताओं, कई संसाधनों को अपडेट करें:

POST /mail/0;1;2/markAsRead;category
POSTDATA: markAsRead=true,category=junk

कई संसाधनों को अपडेट करें, सिर्फ एक विशेषता:

POST /mail/0;1;2/markAsRead
POSTDATA: true

कई विशेषताओं को अपडेट करें, सिर्फ एक संसाधन:

POST /mail/0/markAsRead;category
POSTDATA: markAsRead=true,category=junk

रेस्टफुल क्रिएटिविटी खत्म हो जाती है।


1
कोई यह तर्क दे सकता है कि आपका डिलीट वास्तव में एक पोस्ट होना चाहिए क्योंकि यह वास्तव में उस संसाधन को नष्ट नहीं कर रहा है।
क्रिस निकोला

6
यह आवश्यक नहीं है। POST एक फैक्ट्री-पैटर्न विधि है, यह PUT / DELETE / GET से कम स्पष्ट और स्पष्ट है। एकमात्र उम्मीद यह है कि सर्वर तय करेगा कि पीओएसटी के परिणामस्वरूप क्या करना है। POST वास्तव में ऐसा ही था, मैं फॉर्म डेटा जमा करता हूं और सर्वर कुछ (उम्मीद की उम्मीद) करता है और परिणाम के रूप में मुझे कुछ संकेत देता है। हमें POST के साथ संसाधन बनाने की आवश्यकता नहीं है, हम अक्सर चुनते हैं। मैं आसानी से PUT के साथ एक संसाधन बना सकता हूं, मुझे बस संसाधन URL को प्रेषक के रूप में परिभाषित करना होगा (अक्सर आदर्श नहीं)।
क्रिस निकोला

1
@ निशांत, इस मामले में, आपको शायद यूआरआई में कई संसाधनों को संदर्भित करने की आवश्यकता नहीं है, लेकिन अनुरोध के शरीर में संदर्भ / मूल्यों के साथ केवल ट्यूपल्स पास करें। जैसे, POST / mail / markAsRead, BODY: i_0_id = 0 & i_0_value = true & i_1_id = 1 & i_1_value = false & i_2_id = 2 & i_value = true
Alex

3
अर्धविराम इस उद्देश्य के लिए आरक्षित है।
एलेक्स

1
हैरानी की बात है कि किसी ने भी यह नहीं बताया कि किसी एक संसाधन पर कई विशेषताओं को अपडेट करना अच्छी तरह से कवर किया जाता है PATCH- इस मामले में रचनात्मकता की कोई आवश्यकता नहीं है।
LB2

25

बिल्कुल नहीं - मुझे लगता है कि आरईएसटी समतुल्य है (या कम से कम एक समाधान है) लगभग बिल्कुल यही है - एक विशेष इंटरफ़ेस जिसे क्लाइंट द्वारा आवश्यक ऑपरेशन को समायोजित करना है।

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

ऑब्जेक्ट, अगर मुझे सही ढंग से याद है, तो अनिवार्य रूप से केवल "कमांड" की एक सरणी रखी जाती है - उदाहरण के लिए, अपने उदाहरण को बढ़ाने के लिए, प्रत्येक एक रिकॉर्ड में "markAsRead" कमांड, एक "messageId" और शायद एक कॉलबैक / हैंडलर का संदर्भ हो। फ़ंक्शन - और फिर कुछ शेड्यूल के अनुसार, या कुछ उपयोगकर्ता कार्रवाई पर, कमांड ऑब्जेक्ट को अनुक्रमित किया जाएगा और सर्वर पर पोस्ट किया जाएगा, और क्लाइंट परिणामी पोस्ट-प्रोसेसिंग को हैंडल करेगा।

मेरे पास विवरण के लिए काम नहीं है, लेकिन ऐसा लगता है कि इस तरह की कमांड कतार आपकी समस्या को संभालने का एक तरीका होगा; यह समग्र चंचलता को काफी हद तक कम कर देगा, और यह सर्वर-साइड इंटरफ़ेस को एक तरह से अमूर्त कर देगा, जो आपको सड़क के नीचे और अधिक लचीला लग सकता है।


अपडेट : अहा! मुझे कोड नमूने के साथ पूर्ण, बहुत ऑनलाइन पुस्तक से एक स्निप मिली है (हालांकि मैं अभी भी वास्तविक पुस्तक चुनने का सुझाव देता हूं!)। यहां एक नज़र डालें , जो खंड 5.5.3 से शुरू होता है:

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

कतार दो सरणियों को बनाए रखती है। queued एक संख्यात्मक रूप से अनुक्रमित सरणी है, जिसमें नए अपडेट जोड़े जाते हैं। sent एक सहयोगी सरणी है, जिसमें उन अपडेट हैं जो सर्वर को भेजे गए हैं लेकिन वे उत्तर की प्रतीक्षा कर रहे हैं।

यहाँ दो प्रासंगिक कार्य हैं - एक कतार में कमांड जोड़ने के लिए जिम्मेदार ( addCommand), और एक सीरियल करने के लिए जिम्मेदार है और फिर उन्हें सर्वर ( fireRequest) में भेजा जा रहा है :

CommandQueue.prototype.addCommand = function(command)
{ 
    if (this.isCommand(command))
    {
        this.queue.append(command,true);
    }
}

CommandQueue.prototype.fireRequest = function()
{
    if (this.queued.length == 0)
    { 
        return; 
    }

    var data="data=";

    for (var i = 0; i < this.queued.length; i++)
    { 
        var cmd = this.queued[i]; 
        if (this.isCommand(cmd))
        {
            data += cmd.toRequestString(); 
            this.sent[cmd.id] = cmd;

            // ... and then send the contents of data in a POST request
        }
    }
}

तुम्हें पाने के लिए चाहिए। सौभाग्य!


धन्यवाद। यह मेरे विचारों के समान है कि अगर हम क्लाइंट पर बैच संचालन को कैसे आगे बढ़ाएंगे तो मैं आगे बढ़ूंगा। समस्या बड़ी संख्या में ऑब्जेक्ट पर कार्रवाई करने के लिए राउंड-ट्रिप का समय है।
मार्क रेनॉफ

हम्म, ठीक है - मैंने सोचा था कि आप हल्के अनुरोध के माध्यम से बड़ी संख्या में ऑब्जेक्ट (सर्वर पर) पर ऑपरेशन करना चाहते थे। क्या मुझे गलतफहमी हुई?
क्रिश्चियन न्यूनाटो

हां, लेकिन मैं यह नहीं देख पा रहा हूं कि यह कोड नमूना किसी भी अधिक कुशलता से ऑपरेशन कैसे करेगा। यह अनुरोधों को बैच देता है लेकिन फिर भी उन्हें एक समय में सर्वर पर भेज देता है। क्या मैं गलत व्याख्या कर रहा हूं?
मार्क रेनॉफ

दरअसल यह उन्हें बैचेन करता है और फिर उन्हें एक ही बार में भेजता है: फायर फॉरेंसियर () में लूप के लिए अनिवार्य रूप से सभी बकाया कमांड को इकट्ठा करता है, उन्हें एक स्ट्रिंग के साथ क्रमबद्ध करता है। , 4 "), उस स्ट्रिंग को" डेटा ", और सर्वर को POSTs असाइन करता है।
क्रिश्चियन नूनतो

20

जबकि मुझे लगता है कि @ एलेक्स सही रास्ते के साथ है, वैचारिक रूप से मुझे लगता है कि जो सुझाव दिया गया है उसका उल्टा होना चाहिए।

URL प्रभाव में है "हम जिस संसाधन को लक्षित कर रहे हैं" इसलिए:

    [GET] mail/1

मतलब आईडी 1 के साथ मेल से रिकॉर्ड प्राप्त करें और

    [PATCH] mail/1 data: mail[markAsRead]=true

मतलब आईडी के साथ मेल रिकॉर्ड को पैच करें। querystring एक "फ़िल्टर" है, जो URL से लौटाए गए डेटा को फ़िल्टर करता है।

    [GET] mail?markAsRead=true

इसलिए यहां हम सभी मेल को पहले से ही पढ़े गए के रूप में चिह्नित करने का अनुरोध कर रहे हैं। तो इस पथ को [पथ] कह रहा होगा "पैच रिकॉर्ड को पहले से ही सत्य के रूप में चिह्नित करें" ... जो कि हम हासिल करने की कोशिश नहीं कर रहे हैं।

तो एक बैच विधि, इस सोच का पालन करना चाहिए:

    [PATCH] mail/?id=1,2,3 <the records we are targeting> data: mail[markAsRead]=true

निश्चित रूप से मैं यह नहीं कह रहा हूं कि यह सही REST है (जो बैच रिकॉर्ड हेरफेर को अनुमति नहीं देता है), बल्कि यह REST द्वारा पहले से मौजूद तर्क और उपयोग में है।


दिलचस्प जवाब! अपने अंतिम उदाहरण के लिए, क्या यह (या सिर्फ ) [GET]प्रारूप के अनुरूप नहीं होगा ? इस वैकल्पिक दृष्टिकोण का एक और लाभ यह है कि यदि आप संग्रह में सैकड़ों / हजारों संसाधनों को अपडेट कर रहे हैं तो आप "414 अनुरोध URI बहुत लंबी" त्रुटियों के खिलाफ नहीं चलेंगे। [PATCH] mail?markAsRead=true data: [{"id": 1}, {"id": 2}, {"id": 3}]data: {"ids": [1,2,3]}
rinogo

@rinogo - वास्तव में नहीं। यही वह बिंदु है जो मैं बना रहा था। क्वेरिस्ट्रिंग उन अभिलेखों के लिए एक फ़िल्टर है, जिन पर हम कार्य करना चाहते हैं (उदाहरण। [GET] मेल / 1 को 1 की आईडी के साथ मेल रिकॉर्ड मिलता है, जबकि [GET] मेल? MarkasRead = true रिटर्न मेल जहाँ markAsRead पहले से ही सत्य है)। यह उसी URL को पैच करने का कोई अर्थ नहीं रखता है (अर्थात। उन रिकॉर्ड्स को चिह्नित करें जहां markAsRead = true ") है जब वास्तव में हम आईडी 1,2,3 के साथ विशेष रिकॉर्ड पैच करना चाहते हैं, फ़ील्ड के मौजूदा स्टेटस का पता लगाएं। इसलिए मैंने जिस विधि का वर्णन किया है। सहमत हूं कि कई रिकॉर्ड अपडेट करने में समस्या है। मैं एक कम कसकर युग्मित समापन बिंदु बनाऊंगा।
fezfox

11

आपकी भाषा, "यह बहुत ही बेकार लगता है ...", मेरे लिए समय से पहले अनुकूलन के प्रयास को इंगित करता है। जब तक यह नहीं दिखाया जा सकता है कि वस्तुओं के पूरे प्रतिनिधित्व को भेजना एक प्रमुख प्रदर्शन हिट है (हम उपयोगकर्ताओं को अस्वीकार कर रहे हैं> 150ms के रूप में) तो एक नया गैर-मानक एपीआई व्यवहार बनाने का प्रयास करने का कोई मतलब नहीं है। याद रखें, एपीआई का उपयोग करने में जितना आसान है उतना ही सरल है।

डिलीट के लिए निम्नलिखित भेजें क्योंकि सर्वर को हटाने से पहले ऑब्जेक्ट की स्थिति के बारे में कुछ भी जानने की आवश्यकता नहीं है।

DELETE /emails
POSTDATA: [{id:1},{id:2}]

अगला विचार यह है कि यदि कोई एप्लिकेशन ऑब्जेक्ट के बल्क अपडेट के संबंध में प्रदर्शन के मुद्दों में चल रहा है, तो प्रत्येक ऑब्जेक्ट को कई ऑब्जेक्ट में तोड़ने पर विचार किया जाना चाहिए। इस तरह JSON पेलोड आकार का एक अंश है।

एक उदाहरण के रूप में जब दो अलग-अलग ईमेल के "रीड" और "संग्रहीत" स्टेटस को अपडेट करने के लिए एक प्रतिक्रिया भेजते हैं, तो आपको निम्नलिखित भेजने होंगे:

PUT /emails
POSTDATA: [
            {
              id:1,
              to:"someone@bratwurst.com",
              from:"someguy@frommyville.com",
              subject:"Try this recipe!",
              text:"1LB Pork Sausage, 1 Onion, 1T Black Pepper, 1t Salt, 1t Mustard Powder",
              read:true,
              archived:true,
              importance:2,
              labels:["Someone","Mustard"]
            },
            {
              id:2,
              to:"someone@bratwurst.com",
              from:"someguy@frommyville.com",
              subject:"Try this recipe (With Fix)",
              text:"1LB Pork Sausage, 1 Onion, 1T Black Pepper, 1t Salt, 1T Mustard Powder, 1t Garlic Powder",
              read:true,
              archived:false,
              importance:1,
              labels:["Someone","Mustard"]
            }
            ]

मैं ईमेल के पठनीय घटकों (पढ़ें, संग्रहीत, महत्व, लेबल) को अलग ऑब्जेक्ट में विभाजित कर दूंगा क्योंकि अन्य (से, विषय, पाठ) कभी भी अपडेट नहीं किए जाएंगे।

PUT /email-statuses
POSTDATA: [
            {id:15,read:true,archived:true,importance:2,labels:["Someone","Mustard"]},
            {id:27,read:true,archived:false,importance:1,labels:["Someone","Mustard"]}
          ]

PATCH के उपयोग का लाभ उठाने के लिए एक और तरीका है। स्पष्ट रूप से इंगित करने के लिए कि आप किन गुणों को अद्यतन करने का इरादा कर रहे हैं और सभी अन्य को अनदेखा किया जाना चाहिए।

PATCH /emails
POSTDATA: [
            {
              id:1,
              read:true,
              archived:true
            },
            {
              id:2,
              read:true,
              archived:false
            }
          ]

लोग कहते हैं कि PATCH में परिवर्तन के एक सरणी प्रदान करके लागू किया जाना चाहिए: कार्रवाई (CRUD), पथ (URL), और मूल्य परिवर्तन। इसे एक मानक कार्यान्वयन माना जा सकता है लेकिन यदि आप REST API की संपूर्णता को देखते हैं तो यह एक गैर-सहज ज्ञान युक्त एकल-बंद है। इसके अलावा, उपरोक्त कार्यान्वयन GitHub ने PATCH को कैसे लागू किया है ।

इसे योग करने के लिए, बैच क्रियाओं के साथ Restful सिद्धांतों का पालन करना संभव है और अभी भी स्वीकार्य प्रदर्शन है।


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

हे बेनीरोस, एक टिप्पणी जोड़ने के लिए धन्यवाद, मुझे अक्सर आश्चर्य होता है कि क्या लोग इनमें से कुछ पोस्ट देखते हैं। यह देखकर मुझे खुशी होती है कि लोग ऐसा करते हैं। REST की "स्टेटलेस" प्रकृति के बारे में संसाधन इसे सर्वर के साथ एक चिंता के रूप में परिभाषित करते हैं, जिसमें अनुरोधों पर राज्य बनाए रखने के लिए नहीं है। जैसे, यह मेरे लिए स्पष्ट नहीं है कि आप किस मुद्दे का वर्णन कर रहे थे, क्या आप एक उदाहरण के साथ विस्तृत कर सकते हैं?
justin.hughey

8

Google ड्राइव API में इस समस्या को हल करने के लिए एक बहुत ही दिलचस्प प्रणाली है ( यहाँ देखें )।

वे जो करते हैं, वह मूल रूप से एक Content-Type: multipart/mixedअनुरोध में अलग-अलग अनुरोधों को समूहीकृत करता है , प्रत्येक व्यक्तिगत पूर्ण अनुरोध के साथ कुछ परिभाषित परिसीमन द्वारा अलग किया जाता है। बैच अनुरोध के हेडर और क्वेरी पैरामीटर को व्यक्तिगत अनुरोधों (अर्थात Authorization: Bearer some_token) के लिए विरासत में मिला है, जब तक कि उन्हें व्यक्तिगत अनुरोध में ओवरराइड नहीं किया जाता है।


उदाहरण : (उनके डॉक्स से लिया गया )

निवेदन:

POST https://www.googleapis.com/batch

Accept-Encoding: gzip
User-Agent: Google-HTTP-Java-Client/1.20.0 (gzip)
Content-Type: multipart/mixed; boundary=END_OF_PART
Content-Length: 963

--END_OF_PART
Content-Length: 337
Content-Type: application/http
content-id: 1
content-transfer-encoding: binary


POST https://www.googleapis.com/drive/v3/files/fileId/permissions?fields=id
Authorization: Bearer authorization_token
Content-Length: 70
Content-Type: application/json; charset=UTF-8


{
  "emailAddress":"example@appsrocks.com",
  "role":"writer",
  "type":"user"
}
--END_OF_PART
Content-Length: 353
Content-Type: application/http
content-id: 2
content-transfer-encoding: binary


POST https://www.googleapis.com/drive/v3/files/fileId/permissions?fields=id&sendNotificationEmail=false
Authorization: Bearer authorization_token
Content-Length: 58
Content-Type: application/json; charset=UTF-8


{
  "domain":"appsrocks.com",
   "role":"reader",
   "type":"domain"
}
--END_OF_PART--

उत्तर:

HTTP/1.1 200 OK
Alt-Svc: quic=":443"; p="1"; ma=604800
Server: GSE
Alternate-Protocol: 443:quic,p=1
X-Frame-Options: SAMEORIGIN
Content-Encoding: gzip
X-XSS-Protection: 1; mode=block
Content-Type: multipart/mixed; boundary=batch_6VIxXCQbJoQ_AATxy_GgFUk
Transfer-Encoding: chunked
X-Content-Type-Options: nosniff
Date: Fri, 13 Nov 2015 19:28:59 GMT
Cache-Control: private, max-age=0
Vary: X-Origin
Vary: Origin
Expires: Fri, 13 Nov 2015 19:28:59 GMT

--batch_6VIxXCQbJoQ_AATxy_GgFUk
Content-Type: application/http
Content-ID: response-1


HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Date: Fri, 13 Nov 2015 19:28:59 GMT
Expires: Fri, 13 Nov 2015 19:28:59 GMT
Cache-Control: private, max-age=0
Content-Length: 35


{
 "id": "12218244892818058021i"
}


--batch_6VIxXCQbJoQ_AATxy_GgFUk
Content-Type: application/http
Content-ID: response-2


HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Date: Fri, 13 Nov 2015 19:28:59 GMT
Expires: Fri, 13 Nov 2015 19:28:59 GMT
Cache-Control: private, max-age=0
Content-Length: 35


{
 "id": "04109509152946699072k"
}


--batch_6VIxXCQbJoQ_AATxy_GgFUk--

1

मुझे आपके उदाहरण में एक श्रेणी पार्सर लिखने के लिए एक ऑपरेशन में लुभाया जाएगा।

यह एक पार्सर बनाने के लिए बहुत परेशान नहीं है जो "मैसेजआईड्स = 1-3,7-9,11,12-15" पढ़ सकता है। यह निश्चित रूप से सभी संदेशों को कवर करने वाले कंबल संचालन के लिए दक्षता बढ़ाएगा और अधिक स्केलेबल है।


अच्छा अवलोकन और एक अच्छा अनुकूलन, लेकिन सवाल यह था कि क्या अनुरोध की यह शैली कभी भी REST अवधारणा के साथ "संगत" हो सकती है।
मार्क रेनॉफ

हाय, हाँ, मैं समझता हूँ। अनुकूलन इस अवधारणा को अधिक प्रतिष्ठित बनाता है और मैं अपनी सलाह सिर्फ इसलिए नहीं छोड़ना चाहता था क्योंकि यह विषय से एक छोटा रास्ता भटक रहा था।

1

महान पद। मैं कुछ दिनों के लिए एक समाधान के लिए खोज रहा हूँ। मैं कॉमा द्वारा अलग किए गए बंच आईडी के साथ एक क्वेरी स्ट्रिंग के उपयोग के समाधान के साथ आया था, जैसे:

DELETE /my/uri/to/delete?id=1,2,3,4,5

... तो WHERE INमेरे एसक्यूएल में एक क्लॉज को पारित करना । यह बहुत अच्छा काम करता है, लेकिन आश्चर्य है कि दूसरे इस दृष्टिकोण के बारे में क्या सोचते हैं।


1
मुझे वास्तव में यह पसंद नहीं है क्योंकि यह एक नए प्रकार का परिचय देता है, स्ट्रिंग जिसे आप सूची में जहां में उपयोग करते हैं। मैं इसके बजाय इसे भाषा विशिष्ट प्रकार के लिए पार्स करूंगा और फिर मैं उसी पद्धति का उपयोग कर सकता हूं। सिस्टम के कई अलग-अलग हिस्सों में इसी तरह।
सॉफ्टनर

4
SQL इंजेक्शन के हमलों से सावधान रहने के लिए एक अनुस्मारक और हमेशा अपना डेटा साफ़ करें और इस दृष्टिकोण को लेते समय बाइंड मापदंडों का उपयोग करें।
justin.hughey

2
DELETE /books/delete?id=1,2,3जब पुस्तक # 3 मौजूद नहीं है , तो वांछित व्यवहार पर निर्भर करता है - WHERE INइच्छा चुपचाप अभिलेखों को नजरअंदाज कर देगा, जबकि मैं आमतौर DELETE /books/delete?id=3पर 404 की उम्मीद करूंगा यदि 3 मौजूद है।
chbrown

3
एक अलग समस्या जिसे आप इस समाधान का उपयोग करके चला सकते हैं वह है URL स्ट्रिंग में अनुमत वर्णों की सीमा। यदि कोई व्यक्ति 5,000 रिकॉर्ड्स को बल्क डिलीट करने का निर्णय लेता है तो ब्राउज़र URL को अस्वीकार कर सकता है या HTTP सर्वर (उदाहरण के लिए अपाचे) इसे अस्वीकार कर सकता है। सामान्य नियम (जो उम्मीद है कि बेहतर सर्वर और सॉफ्टवेयर के साथ बदल रहा है) को 2KB के अधिकतम आकार के साथ जाना है। जहां एक POST की बॉडी के साथ आप 10MB तक जा सकते हैं। stackoverflow.com/questions/2364840/…
justin.hughey

0

मेरे दृष्टिकोण से मुझे लगता है कि फेसबुक का सबसे अच्छा कार्यान्वयन है।

एक एकल HTTP अनुरोध बैच पैरामीटर और एक टोकन के लिए बनाया गया है।

बैच में एक जसन भेजा जाता है। जिसमें "अनुरोधों" का एक संग्रह होता है। प्रत्येक अनुरोध में एक विधि संपत्ति होती है (प्राप्त / पोस्ट / डाल / हटाएं / आदि ...), और एक रिश्तेदार_उर्ल संपत्ति (समापन बिंदु की यूआरआई), इसके अलावा पोस्ट और विधियों को "बॉडी" संपत्ति की अनुमति दें जहां फ़ील्ड को अपडेट किया जाए भेज दिए गए हैं ।

अधिक जानकारी पर: फेसबुक बैच एपीआई

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