REST वेब सेवा में क्रिया को ट्रिगर करने के लिए मुझे किस HTTP क्रिया का उपयोग करना चाहिए?


80

मैं एक Restful वेब सेवा को लागू कर रहा हूं और उपलब्ध कार्यों में से एक होगा reload। इसका उपयोग कॉन्फ़िगरेशन, कैश आदि को फिर से लोड करने के लिए किया जाएगा।

हमने GETइस तरह से एक यूआरआई के लिए एक सरल के साथ शुरुआत की : ${path}/cache/reload(कोई पैरामीटर पारित नहीं किया जाता है, केवल यूआरआई कहा जाता है)। मुझे पता है कि जीईटी अनुरोध के साथ डेटा को संशोधित नहीं किया जाना चाहिए।

RESTful वेब सेवा में किसी क्रिया / आदेश को लागू करने के लिए उपयोग करने के लिए कौन सी क्रिया सही है?

रीलोड REST वेब सेवा का एक कमांड है जो अपने स्वयं के कैश / कॉन्फ़िगरेशन / आदि को फिर से लोड करता है। यह एक विधि नहीं है जो क्लाइंट को जानकारी लौटाती है।

संभवतः मैं जो करने की कोशिश कर रहा हूं वह REST नहीं है, लेकिन यह अभी भी कुछ है जिसे इस तरह से करने की आवश्यकता है। reloadविधि केवल एक वास्तविक उदाहरण है कि आवेदन के दायरे में भावना और सबसे यह पर ध्यान केंद्रित जवाब बनाता था, लेकिन वास्तव में, मैं सिर्फ जानना चाहता है जो क्रिया, एक कार्रवाई है कि CRUD नहीं करता है को गति प्रदान करने के लिए आवश्यक है लेकिन अभी भी डेटा में परिवर्तन / राज्य।

मैंने स्टैक ओवरफ्लो पर इस विस्तृत asnwer को इस विषय पर पाया: https://stackoverflow.com/questions/16877968/


1
"पुनः लोड करना" एक ऐप की समझ है जो डेटा को प्रदर्शित करने के लिए ताज़ा करता है? क्या पुनः लोड करने और केवल डेटा फिर से प्राप्त करने के बीच कोई अंतर है?
शॉन रेडमंड

1
@SeanRedmond नहीं, डेटा क्लाइंट को नहीं भेजा जाता है। वास्तव में, ग्राहक REST वेब सेवा को निष्पादित और आंतरिक कमांड (पुनः लोड) करने के लिए कह रहा है। कुछ इस तरह: "डेटाबेस में बहुत सारे कॉन्फ़िगरेशन बदल दिए गए थे, इसलिए REST वेब सेवा, उन्हें अब आपकी मेमोरी में पुनः लोड करें"।
रेनैटो दिनानी

क्रॉस-साइट डुप्लिकेट: stackoverflow.com/q/15340946/319403
cHao

क्या आपने उचित अनुरोधों पर हेडर पैरामीटर का उपयोग करने पर विचार किया है? यह बहुत अच्छा लगता है एक कैश रिफ्रेश ...
गुरन

जवाबों:


25

मुझे नहीं लगता कि इस कार्रवाई के लिए एक उचित क्रिया है क्योंकि यह लेनदेन वास्तव में "रेस्टफुल" नहीं है। "एस" और "टी" "राज्य हस्तांतरण" के लिए खड़े हैं और यहां कुछ भी स्थानांतरित नहीं किया जा रहा है। या, एक और रास्ता रखो, सबसे सख्त परिभाषा के अनुसार, PUT और POST जैसी क्रियाओं का उपयोग हमेशा एक संज्ञा के साथ किया जाता है और "पुनः लोड" में केवल क्रिया होती है।

यह रीलोड रेस्टफुल नहीं हो सकता है, लेकिन यह अभी भी उपयोगी हो सकता है और आपके पास इसे करने का एक तरीका होगा और इसके साथ रहना या समझाना होगा कि यह असामान्य है। GET शायद सबसे सरल है। टिप्पणियों में उचित मात्रा में संदेह है, हालांकि, इसलिए आपको इस बारे में सोचना चाहिए कि क्या इस पुनः लोड कार्रवाई की आवश्यकता है या नहीं, क्योंकि कुछ और ऐसा नहीं कर रहा है जो इसे करना चाहिए।


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

@Aaron, idempotent और nullimpotent की तुलना सभी अच्छी तरह से और अच्छी है, लेकिन आप यह कैसे निर्धारित करते हैं कि यह ध्यान देने योग्य नहीं है?
क्रेग

@ क्रैग यह बहुत ही अच्छा है अगर इसे कई बार चलाने पर एक बार इसे चलाने का समान प्रभाव पड़ता है। यदि यह एक बार या कई बार चल रहा है तो शून्य पर इसे शून्य बार चलाने के रूप में सर्वर पर समान प्रभाव पड़ता है। en.wikipedia.org/wiki/Idempotence
एरोन ग्रीनवल्ड

5
@AaronGreenwald "notimpotent" [not-im-poht-nt] [not-im-pawr-tnt] - विशेषण - 1. शब्दों पर एक नाटक, "महत्वपूर्ण नहीं", विशेषण का "antonym" महत्वपूर्ण। 2. हास्य ... 2. हास्य ... ;-)
क्रेग

@ क्रेग मैं पूरी तरह से चूक गया :)
हारून

75

यदि आप चाहते हैं कि RESTful क्रिया करने के लिए क्रिया के बारे में न सोचें, तो सोचें कि जिस स्थिति में आप चाहते हैं कि ग्राहक कुछ करने के बाद संसाधन की आवश्यकता हो।

तो ऊपर दिए गए आपके एक उदाहरण का उपयोग करके आपके पास एक ईमेल कतार है जो ईमेल भेज रही है। आप चाहते हैं कि क्लाइंट उस ईमेल कतार को रुके या रुके या कुछ और करने की स्थिति में रखे।

तो क्लाइंट उस संसाधन के लिए सर्वर को एक नया राज्य देता है। यह JSON जितना सरल हो सकता है

PUT http://myserver.com/services/email_service HTTP/1.1
Content-Type: text/json

{"status":"paused"}

सर्वर यह पता लगाता है कि वर्तमान स्थिति ("चल") से "रुका हुआ" स्थिति / स्थिति कैसे प्राप्त करें।

यदि ग्राहक संसाधन पर एक GET करता है तो उसे उस स्थिति को वापस कर देना चाहिए जो वर्तमान में है ("रुका हुआ")।

इस तरह से करने का कारण, और REST इतना शक्तिशाली क्यों हो सकता है, यह है कि आप सर्वर को उस स्थिति तक लाने के लिए HOW को कैसे छोड़ते हैं।

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

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


2
जहां तक ​​मेरा सवाल है यह सही उत्तर है। सर्वर पर डेटा रीफ्रेश करना एक बेकार ऑपरेशन नहीं है, और GETउपयोग करने के लिए पूरी तरह से अनुचित क्रिया है। PUTसबसे उपयुक्त क्रिया है क्योंकि ऑपरेशन को कैश के "पुनः लोड की गई स्थिति" को "पुनः लोड" करने के लिए अद्यतन करने के रूप में सोचा जा सकता है।
Jez

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

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

... हालांकि मुझे लगता है कि मैं इस मामले में POST को प्राथमिकता दूंगा, क्योंकि PUT को भी निष्प्रभावी माना जाता है, लेकिन POST इस तरह की अड़चन नहीं है।
क्रेग

1
आप ऐसा कर सकते हैं, लेकिन अंततः यह एक चौकोर खूंटी को गोल छेद में फिट करने की कोशिश कर रहा है। कोई कारण नहीं है कि क्लाइंट को कुछ भी "पुनः लोड" करने के लिए सर्वर को ट्रिगर करने की आवश्यकता है, जो कि सिर्फ खराब वास्तुशिल्प डिजाइन है। या तो सर्वर प्रत्येक कॉल पर या निश्चित समय अंतराल पर अपनी आंतरिक स्थिति को अपडेट कर सकता है। सर्वर पर संसाधन राज्य के लिए किसी भी वास्तविक अनुरोध के स्वतंत्र कुछ पुनः लोड करने के लिए सर्वर को बताने के लिए भरोसा करना आर्किटेक्चर नहीं है।
कॉर्मैक मुल्हल

32

स्वीकृत उत्तर सहित कुछ अन्य उत्तर, आपको GET (हालांकि बहुत उत्साह से नहीं) का उपयोग करने की सलाह देते हैं।

मैं असहमत हूं।

सबसे पहले, सभी अन्य आपको बता रहे हैं कि यह आदर्श नहीं है और वास्तव में Restful सही नहीं हैं। उचित रीस्टफ़ुल परिदृश्य में, आप सर्वर पर संसाधनों में हेरफेर कर रहे हैं और उन संसाधनों को जोड़ रहे हैं, अपडेट कर रहे हैं, हटा रहे हैं, पुनः प्राप्त कर रहे हैं, आदि। PUT को एक पेलोड भेजना चाहिए जो अनुरोध पूरा होने पर संसाधन का प्रतिनिधित्व करता है, और POST को एक पेलोड भेजना चाहिए जो सर्वर में जोड़े जाने वाले संसाधन का प्रतिनिधित्व करता है। और जीईटी को सर्वर पर एक संसाधन वापस करना चाहिए।

आपके पास RPC (दूरस्थ प्रक्रिया कॉल) है, जो कि Restful नहीं है - आप सर्वर पर कुछ करना चाहते हैं। इसलिए यदि आप विशुद्ध रूप से Restful API बनाने की कोशिश कर रहे हैं, तो आपको इस बात पर पुनर्विचार करना चाहिए कि आप क्या कर रहे हैं।

उस ने कहा, कभी-कभी आपको नियमों को थोड़ा मोड़ने की आवश्यकता होती है। खासकर यदि आप एक आंतरिक एपीआई विकसित कर रहे हैं जो जनता के सामने नहीं आने वाला है, तो आप यह तय कर सकते हैं कि व्यापार बंद हो।

यदि आप करते हैं, तो मैं एक PUT या POST की सिफारिश करूंगा, जो इस बात पर निर्भर करता है कि RPC निष्क्रिय है या नहीं।

सामान्य तौर पर, हम कहते हैं कि HTTP PUT मैप्स को SQL UPDATE और उस HTTP POST मैप्स को SQL INSERT में मैप करता है, लेकिन यह कड़ाई से सच नहीं है। यह बताने का एक शुद्ध तरीका है कि HTTP PUT को सुस्पष्ट होना चाहिए और HTTP POST की आवश्यकता नहीं होनी चाहिए। इसका मतलब है कि आप एक ही PUT अनुरोध को कई बार कॉल कर सकते हैं जैसा कि आप बिना किसी साइड-इफेक्ट के चाहते हैं। एक बार जब आप इसे कॉल कर लेते हैं, तो इसे दोबारा कॉल करने के लिए हानिरहित होता है। लेकिन आपको बार-बार POST अनुरोधों को कॉल नहीं करना चाहिए जब तक कि आपका मतलब नहीं है - प्रत्येक POST सर्वर पर डेटा को फिर से बदलता है।

आपके मामले में, यदि आपको यह पुनः लोड करने की आवश्यकता है, तो मैं एक PUT की सलाह दूंगा क्योंकि यह ऐसा लगता है जैसे कि यह बेकार है। लेकिन मैं फिर भी आपसे आग्रह करूंगा कि आप इस पर विचार करें कि दूसरों ने इसके बारे में क्या कहा है।


6

POSTऔर PUTएक वेब सर्वर के लिए एक इकाई प्रस्तुत करने के लिए इस्तेमाल HTTP क्रिया हैं। इसके साथ PUT, प्रस्तुत इकाई दिए गए URI में संसाधन के लिए एक नया (नया) प्रतिनिधित्व है, जो कि आप जो चाहते हैं वह फिट नहीं है। POSTपारंपरिक फॉर्म-हैंडलर के लिए है, जहां इकाई संसाधन के लिए सहायक डेटा है, इसलिए वह विजेता है। इकाई में कमांड या एक्शन (जैसे "एक्शन = रीलोड") शामिल होगा।

उस ने कहा, विचाराधीन कमांड को शायद REST इंटरफ़ेस के माध्यम से उजागर नहीं किया जाना चाहिए। यह "पुनः लोड" के लिए आवश्यकता की तरह लगता है क्योंकि डेटा को किसी अन्य चैनल (जैसे फाइल सिस्टम, डीबी क्लाइंट) के माध्यम से बदला जा सकता है। कैश पारदर्शी होना चाहिए। इसके अलावा, HTTP अनुरोधों को परमाणु होना चाहिए, यहां तक ​​कि अन्य चैनलों पर भेजे गए संदेशों को भी ध्यान में रखना चाहिए। कॉन्फ़िगरेशन सेटिंग्स के लिए "रीलोड" कमांड की पेशकश एक अनावश्यक जटिलता लगती है; यह एक भंगुर डिजाइन की आवश्यकता है। किसी अन्य चैनल के माध्यम से अपडेट के बाद "पुनः लोड" को साफ करने के लिए एक्सपोज करना गंदा है क्योंकि एक चैनल में पूरी बातचीत नहीं होती है। इसके बजाय, इनमें से एक पर विचार करें:

  • REST के माध्यम से पूरी तरह से अपडेट करना
  • दूसरे चैनल को कमांड (ओं) को उजागर करना
  • कार्यों को स्वचालित करना

उन विकल्पों में से कुछ व्यवहार्य नहीं हो सकते हैं, जो अन्य प्रतिबंधों पर निर्भर करते हैं।

" पूस्ट बनाम POST in REST " भी देखें ।


धन्यवाद। मैंने संपादन का "आंतरिक" हटा दिया क्योंकि वास्तव में "पुनः लोड" विधि का उद्देश्य सार्वजनिक होना है। मैंने सिर्फ यह अर्थ निकालने की कोशिश की कि यह वेब सेवा को ही संदर्भित करता है। मुझे लगता है कि "एक्शन" पोस्ट करना एक अच्छा तरीका होगा।
रेनैटो दिनानी

@ RenatoDinhaniConceição: यहां तक ​​कि "आंतरिक" के बिना, यह अभी भी बदबू आ रही है। यह हो सकता है कि आप एक नया प्रश्न पूछें कि क्या डिजाइन एक अच्छा है।
outis

4

मैं तर्क दूंगा कि ग्राहक अनुरोध को स्पष्ट रूप से ऐसा कुछ करने के लिए कॉल करने की आवश्यकता क्यों होगी। ऐसा लगता है कि या तो जीईटी (आई पुल डेटा) के अधिक विशिष्ट कार्यान्वयन पर छिपे हुए तर्क होना चाहिए, लेकिन सेवा डेटा को खींचे जाने से पहले एक ताज़ा बनाता है), या क्लाइंट से दूर बैकएंड में एक और ट्रिगर द्वारा।

आखिरकार, डेटा / कॉन्फिगर को केवल बाद की कॉल पर चालू करने की आवश्यकता होगी, इसलिए मैं डेटा रीफ़्रेश के लिए एक आलसी बनाम उत्सुक कॉल की ओर अधिक झुकूंगा। जाहिर है मैं यहां बहुत कुछ मान रहा हूं, लेकिन मैं इस तरह के एक स्पष्ट और स्टैंडअलोन कॉल की आवश्यकता का पुनर्मूल्यांकन करने के लिए कदम उठाऊंगा।


मेरे संपादन को देखो। "पुनः लोड" एक कमांड नहीं है जो डेटा लौटाता है। यह स्वयं REST वेब सेवा को संदर्भित करता है। सामान्य शब्दों में, मेरा प्रश्न एक REST वेब सेवा में क्रियाओं को ट्रिगर करने के बारे में है। अन्य उदाहरण हो सकता है: email_queue/stop_sending_emails। मैं एक RESTful इंटरफ़ेस का उपयोग करके कुछ को कमांड दे रहा हूं।
रेनाटो दीन्हानी

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

1
मैं सहमत हूँ। कॉन्फ़िगरेशन और कैशिंग जैसी चीजें क्लाइंट के लिए पारदर्शी होनी चाहिए। हो सकता है कि आप हमें एक ऐसी स्थिति का अधिक ठोस विवरण दें जिसमें आपका समापन बिंदु कहा जाएगा।
बेंजामिन हॉजसन 21

3

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

शुद्धतावादियों के लिए, आपके पास इसके लिए एक समर्पित आग्रह हो सकता है। ध्यान दें कि आप इसे विस्तारित कर सकते हैं और डेटाबेस में वास्तविक क्रियाओं को लॉग इन कर सकते हैं (या जो भी संग्रहण) दिनांक, स्थिति, उपयोगकर्ता, आदि के साथ ... बस यहां मेरे विचार।

सामान्य प्रणाली चौड़ा संचालन / क्रिया / {क्रिया}

संसाधन प्रकार / क्रिया / {संसाधन} / {क्रिया} के लिए विशिष्ट ऑपरेशन

किसी संसाधन / क्रिया / {संसाधन} / {id} / {क्रिया} के लिए विशिष्ट ऑपरेशन

आपके मामले में, कैश संभवतः सिस्टम-वाइड / एक्शन / reload_cache है


0

REST वेब सेवा में क्रिया को ट्रिगर करने के लिए मुझे किस HTTP क्रिया का उपयोग करना चाहिए?

एक REST सेवा के विवरण पर विचार करते समय, इस अनुमान पर विचार करना अक्सर उपयोगी होता है: आप इसे वेब साइट के साथ कैसे लागू करेंगे?

HTML केवल मूल रूप से GET और POST अनुरोधों का वर्णन कर सकती है। तो हम शुरू कर सकते हैं वहाँ खोज रहे हैं।

है GETउचित? इस प्रश्न का उत्तर देने के लिए, हमें उन मान्यताओं के बारे में सोचने की आवश्यकता है जिनके बारे में ग्राहकों और मध्यवर्ती घटकों को बनाने की अनुमति है GET। के शब्दों GETरहे हैं सुरक्षित

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

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

इसका उपयोग कॉन्फ़िगरेशन, कैश आदि को फिर से लोड करने के लिए किया जाएगा।

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

POSTदूसरी ओर, प्रभावी रूप से अप्रतिबंधित है - यह उन मान्यताओं को बहुत कम कर देता है जिन्हें सामान्य ग्राहकों को बनाने की अनुमति है। आपको सट्टा POST अनुरोध करने वाले घटक नहीं मिलते हैं क्योंकि वे ऐसा करने के लिए दोषपूर्ण होंगे - मानक में कुछ भी नहीं कहता है कि ठीक है।

PUT, ... ये असुरक्षित तरीके हैं PATCH, DELETEजिनकी तुलना में अधिक विशिष्ट शब्दार्थ हैं POST; वे उपयुक्त हैं या नहीं, यह आपके संसाधन मॉडल पर निर्भर करता है।

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

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