किसी RESTful मार्ग में संसाधन पर सर्वर-साइड पद्धति को कॉल करें


142

ध्यान रखें मुझे REST की अल्पविकसित समझ है। मान लें कि मेरे पास यह URL है:

http://api.animals.com/v1/dogs/1/

और अब, मैं सर्वर को कुत्ते की छाल बनाना चाहता हूं। केवल सर्वर को पता है कि यह कैसे करना है। मान लीजिए कि मैं इसे एक CRON जॉब पर चलाना चाहता हूं, जो बाकी के 10 मिनटों के लिए कुत्ते की छाल बना दे। वह कॉल कैसा दिखता है? मैं यह करना चाहता हूँ:

URL अनुरोध:

ACTION http://api.animals.com/v1/dogs/1/

अनुरोध निकाय में:

{"action":"bark"}

इससे पहले कि आप अपना खुद का HTTP मेथड बनाने के लिए मुझ पर तरस खाएं, मेरी मदद करें और मुझे इस बारे में बेहतर जानकारी दें कि मुझे सर्वर-साइड पद्धति को कैसे RESTful तरीके से लागू करना चाहिए। :)

आनंद के लिए संपादित करें

"छाल" विधि क्या करती है, इसके आसपास कुछ और स्पष्टीकरण। यहां कुछ विकल्प दिए गए हैं जिनके परिणामस्वरूप अलग-अलग संरचित API कॉल हो सकते हैं:

  1. छाल सिर्फ dog.email को एक ईमेल भेजता है और कुछ भी रिकॉर्ड नहीं करता है।
  2. छाल dog.email और increments dog.barkCount को 1 द्वारा एक ईमेल भेजता है।
  3. छाल का इलाज होने पर छाल के साथ एक नया "बार्क" रिकॉर्ड बनाता है। यह 1 से dog.barkCount को भी बढ़ाता है।
  4. छाल गितुब से कुत्ते कोड के नवीनतम संस्करण को खींचने के लिए एक सिस्टम कमांड चलाता है। फिर यह dog.owner को एक टेक्स्ट संदेश भेजता है जिसमें उन्हें बताया गया है कि नया कुत्ता कोड उत्पादन में है।

14
दिलचस्प है, एक इनाम जोड़ने से प्रतीत होता है कि मूल रूप से आपके पास इससे भी बदतर जवाब आकर्षित हुए हैं;; जब उत्तर का मूल्यांकन करते हैं तो याद रखें कि: 1) HTTP क्रिया के लिए चश्मा POST के अलावा किसी भी विकल्प को छोड़ देते हैं। 2) REST का URL संरचना से कोई लेना-देना नहीं है - यह लाभ (स्केलेबिलिटी, विश्वसनीयता, दृश्यता, आदि) की तुलना में कंट्रोन्स (स्टेटलेस, कैचएबल, लेयर्ड, यूनिफ़ॉर्म इंटरफेस आदि) की एक सामान्य सूची है। 3) वर्तमान प्रथा (जैसे RPC स्पेक्स में POST का उपयोग करना) उन परिभाषावादियों को परेशान करती है जो अपने एपीआई नियम बना रहे हैं। 4) REST को एक समान इंटरफ़ेस (HTTP कल्पना के बाद) की आवश्यकता होती है।
रेमंड हेटिंगर

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

@RaymondHettinger PATCHउपयुक्त हो सकता है। मैं समझाता हूं कि मेरे उत्तर के अंत की ओर क्यों ।
जॉर्डन

PATCH केवल एक कुत्ते को बढ़ाने के लिए उपयुक्त होगा । POST ईमेल भेजने, एक नया छाल रिकॉर्ड बनाने, गितुब से डाउनलोड करने के लिए कमांड चलाने या टेक्स्ट संदेश को ट्रिगर करने की विधि है। @ जोर्डन, PATCH RFC का आपका पढ़ना कल्पनाशील है लेकिन आंशिक संसाधन संशोधन के लिए PUT के एक संस्करण के रूप में इसके इरादे से कुछ हद तक है। मुझे नहीं लगता कि आप दूरस्थ प्रक्रिया कॉल के लिए POST का उपयोग करने के मानक अभ्यास को स्वीकार करने के बजाय HTTP चश्मा के अपरंपरागत रीडिंग के साथ आकर ओपी की मदद कर रहे हैं।
रेमंड हेटिंगर

@RaymondHettinger किसका अभ्यास वास्तव में POST का मानकीकरण करता है? सभी मानक RPC इंटरफेस मैंने इकाई (RESTful नहीं) बनाम URI द्वारा एक संसाधन की पहचान करते हुए देखे हैं, इसलिए RPC सम्मेलन को प्राथमिकता देने वाले एक मान्य उत्तर को वैसे भी अपरंपरागत बनाने की आवश्यकता होगी, जो मुझे लगता है कि पारंपरिक RPC के मूल्य को रोक देता है, एक कल्पनाशील या असंगत है । आप POST के साथ कभी भी गलत नहीं हो सकते क्योंकि यह डेटा प्रोसेसिंग के लिए कैच-ऑल है, लेकिन अधिक विशिष्ट तरीके हैं। REST का अर्थ है संसाधनों का नामकरण और उनके राज्य में परिवर्तन का वर्णन करना, न कि राज्य-परिवर्तन प्रक्रियाओं का नामकरण। PATCH और POST दोनों ही राज्य परिवर्तनों का वर्णन करते हैं।
जॉर्डन

जवाबों:


280

एक उद्देश्यपूर्ण डिजाइन के लिए क्यों?

रेस्टफुल सिद्धांत वेब सेवाओं एपीआई डिजाइन के लिए वेब साइटों को आसान बनाने के लिए ( यादृच्छिक मानव उपयोगकर्ता के लिए "सर्फ" करने के लिए) सुविधाएँ लाते हैं , इसलिए वे प्रोग्रामर का उपयोग करना आसान है। REST अच्छा नहीं है क्योंकि यह REST है, यह अच्छा है क्योंकि यह अच्छा है। और यह ज्यादातर अच्छा है क्योंकि यह सरल है

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

लेकिन REST सिल्वर बुलट नहीं है: कभी-कभी एक RPC- शैली ("रिमोट प्रक्रिया कॉल" - जैसे SOAP) उपयुक्त हो सकती है , और कभी-कभी अन्य आवश्यकताओं को वेब के गुणों पर पूर्वता प्राप्त होती है। यह ठीक है। जो हमें वास्तव में पसंद नहीं है, वह है अनावश्यक जटिलता । अक्सर एक प्रोग्रामर या एक कंपनी एक नौकरी के लिए आरपीसी-शैली सेवाओं को लाती है जो सादे पुराने एचटीटीपी को ठीक से संभाल सकती है। इसका प्रभाव यह है कि HTTP एक विशाल XML पेलोड के लिए परिवहन प्रोटोकॉल में कम हो गया है, जो बताता है कि "वास्तव में" क्या चल रहा है (URI या HTTP विधि इसके बारे में कोई सुराग नहीं देता है)। परिणामी सेवा अब तक बहुत जटिल है, डिबग करना असंभव है, और तब तक काम नहीं करेगा जब तक कि आपके क्लाइंट का डेवलपर के अनुसार सटीक सेटअप न हो

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

💡 कार्यों के संदर्भ में सोचने के बजाय यह प्रदर्शन कर सकता है ("मानचित्र पर स्थानों की खोज करें") ...

... उन कार्यों के परिणामों के बारे में सोचने की कोशिश करें ("मानचित्र पर स्थानों की सूची एक खोज मापदंड से मेल खाती है")।

मैं नीचे के उदाहरणों के लिए जाऊँगा। (REST का अन्य मुख्य पहलू HATEOAS का उपयोग है - मैं इसे यहाँ ब्रश नहीं करता, लेकिन मैं इसके बारे में किसी भी पोस्ट पर जल्दी से बात करता हूं ।)


पहले डिजाइन के मुद्दे

आइए एक नज़र डालते हैं प्रस्तावित डिजाइन:

ACTION http://api.animals.com/v1/dogs/1/

सबसे पहले, हमें एक नया HTTP वर्ब ( ACTION) बनाने पर विचार नहीं करना चाहिए । सामान्यतया, यह कई कारणों से अवांछनीय है:

  • (1) केवल सेवा URI को देखते हुए, "यादृच्छिक" प्रोग्रामर को पता चलेगा कि ACTIONक्रिया कैसे मौजूद है?
  • (२) यदि प्रोग्रामर जानता है कि यह मौजूद है, तो वह इसके शब्दार्थ को कैसे जान पाएगा? उस क्रिया का क्या अर्थ है?
  • (३) क्या गुण (सुरक्षा, मूर्खता) किसी को उस क्रिया की अपेक्षा करनी चाहिए?
  • (4) क्या होगा यदि प्रोग्रामर के पास एक बहुत ही सरल क्लाइंट है जो केवल मानक HTTP क्रियाओं को संभालता है?
  • (५) ...

अब आइए उपयोग करने पर विचार करेंPOST (मैं चर्चा करूंगा कि नीचे क्यों, अभी इसके लिए मेरा शब्द लें):

POST /v1/dogs/1/ HTTP/1.1
Host: api.animals.com

{"action":"bark"}

यह ठीक हो सकता है ... लेकिन केवल अगर :

  • {"action":"bark"}एक दस्तावेज था; तथा
  • /v1/dogs/1/एक "दस्तावेज़ प्रोसेसर" (कारखाना जैसा) यूआरआई था। एक "डॉक्यूमेंट प्रोसेसर" एक यूआरआई है जिसे आप केवल "चीजों को फेंक" देते हैं और उनके बारे में "भूल जाते हैं" - प्रोसेसर आपको "फेंकने" के बाद एक नए बनाए गए संसाधन पर पुनर्निर्देशित कर सकता है। उदाहरण के लिए URI एक संदेश ब्रोकर सेवा पर संदेश पोस्ट करने के लिए, जो कि पोस्ट करने के बाद आपको URI के लिए पुनर्निर्देशित करेगा जो संदेश के प्रसंस्करण की स्थिति दिखाता है।

मुझे आपके सिस्टम के बारे में ज्यादा जानकारी नहीं है, लेकिन मैं शर्त लगा सकता हूं कि दोनों सच नहीं हैं:

  • {"action":"bark"} कोई दस्तावेज़ नहीं है , यह वास्तव में वह तरीका है जिसे आप सेवा में निंजा-चुपके की कोशिश कर रहे हैं ; तथा
  • /v1/dogs/1/यूआरआइ एक "कुत्ता" संसाधन (शायद के साथ कुत्ते का प्रतिनिधित्व करता है id==1) और नहीं एक दस्तावेज प्रोसेसर।

तो अब हम जानते हैं कि ऊपर का डिज़ाइन इतना Restful नहीं है, लेकिन वास्तव में ऐसा क्या है? इसके बारे में इतना बुरा क्या है? मूल रूप से, यह बुरा है क्योंकि जटिल URI जटिल अर्थों के साथ है। आप इससे कुछ भी अनुमान नहीं लगा सकते। एक प्रोग्रामर को कैसे पता चलेगा कि एक कुत्ते के पास एक ऐसी barkकार्रवाई है जिसे गुप्त रूप से एक साथ संक्रमित किया जा सकता POSTहै?


अपने प्रश्न के एपीआई कॉल को डिजाइन करना

तो चलो पीछा करने के लिए कटौती करते हैं और संसाधनों के संदर्भ में सोचकर उन छालों को डिजाइन करने का प्रयास करते हैं । मुझे रेस्टफुल वेब सेवा पुस्तक को उद्धृत करने की अनुमति दें :

एक POSTअनुरोध पहले से मौजूद किसी से एक नया संसाधन पैदा करने की कोशिश है। मौजूदा संसाधन डेटा-संरचना अर्थों में नए के माता-पिता हो सकते हैं, जिस तरह से एक पेड़ की जड़ उसके सभी पत्तों के नोड्स के माता-पिता हैं। या मौजूदा संसाधन एक विशेष "कारखाना" संसाधन हो सकता है जिसका एकमात्र उद्देश्य अन्य संसाधनों को उत्पन्न करना है। POSTअनुरोध के साथ भेजा गया प्रतिनिधित्व नए संसाधन की प्रारंभिक स्थिति का वर्णन करता है। PUT के साथ, एक POSTअनुरोध को सभी में एक प्रतिनिधित्व शामिल करने की आवश्यकता नहीं है।

ऊपर दिए गए विवरण के बाद हम देख सकते हैं कि barkइसे एक के उप-स्रोत केdog रूप में तैयार किया जा सकता है (क्योंकि barkयह एक कुत्ते के भीतर निहित है, अर्थात, एक कुत्ते द्वारा छाल "छाल" है )।

उस तर्क से हम पहले ही मिल गए:

  • विधि है POST
  • संसाधन है /barks, कुत्ते का उप- स्रोत : "कारखाने" का /v1/dogs/1/barksप्रतिनिधित्व करना bark। यह URI प्रत्येक कुत्ते के लिए अद्वितीय है (क्योंकि यह नीचे है /v1/dogs/{id})।

अब आपकी सूची के प्रत्येक मामले का एक विशिष्ट व्यवहार है।

1. छाल सिर्फ ई-मेल भेजता है dog.emailऔर कुछ भी रिकॉर्ड नहीं करता है।

सबसे पहले, एक ई-मेल भेजना (एक ई-मेल भेजना) एक समकालिक या एक अतुल्यकालिक कार्य है? दूसरे barkअनुरोध में किसी भी दस्तावेज़ (ई-मेल, शायद) की आवश्यकता होती है या क्या यह खाली है?


1.1 छाल एक ई-मेल भेजता है dog.emailऔर कुछ भी रिकॉर्ड नहीं करता है (एक तुल्यकालिक कार्य के रूप में)

यह मामला सरल है। barksफैक्ट्री रिसोर्स पर कॉल करने पर तुरंत एक बार्क (एक ई-मेल भेजा गया) और रिस्पॉन्स मिलता है (यदि ठीक है या नहीं) तुरंत दिया जाता है:

POST /v1/dogs/1/barks HTTP/1.1
Host: api.animals.com
Authorization: Basic mAUhhuE08u724bh249a2xaP=

(entity-body is empty - or, if you require a **document**, place it here)

200 OK

जैसा कि यह रिकॉर्ड (परिवर्तन) कुछ भी नहीं है, 200 OKपर्याप्त है। यह दिखाता है कि सब कुछ उम्मीद के मुताबिक चला।


1.2 छाल एक ई-मेल भेजता है dog.emailऔर कुछ भी रिकॉर्ड नहीं करता है (एक अतुल्यकालिक कार्य के रूप में)

इस स्थिति में, क्लाइंट के पास barkकार्य को ट्रैक करने का एक तरीका होना चाहिए । इसके barkबाद कार्य यूआईआरआई के पास होना चाहिए।

POST /v1/dogs/1/barks HTTP/1.1
Host: api.animals.com
Authorization: Basic mAUhhuE08u724bh249a2xaP=

{document body, if needed;
NOTE: when possible, the response SHOULD contain a short hypertext note with a hyperlink
to the newly created resource (bark) URI, the same returned in the Location header
(also notice that, for the 202 status code, the Location header meaning is not
standardized, thus the importance of a hipertext/hyperlink response)}

202 Accepted
Location: http://api.animals.com/v1/dogs/1/barks/a65h44

इस तरह, प्रत्येक barkट्रेस करने योग्य है। क्लाइंट तब यह जानने के GETलिए barkURI को जारी कर सकता है कि यह वर्तमान स्थिति है। शायद DELETEइसे रद्द करने के लिए भी उपयोग करें ।


2. छाल एक ई-मेल भेजती है dog.emailऔर फिर dog.barkCount1 से बढ़ जाती है

यह एक dogमुश्किल हो सकता है, यदि आप ग्राहक को यह बताना चाहते हैं कि संसाधन बदल जाता है:

POST /v1/dogs/1/barks HTTP/1.1
Host: api.animals.com
Authorization: Basic mAUhhuE08u724bh249a2xaP=

{document body, if needed; when possible, containing a hipertext/hyperlink with the address
in the Location header -- says the standard}

303 See Other
Location: http://api.animals.com/v1/dogs/1

इस मामले में, locationहेडर का इरादा ग्राहक को यह बताने का है कि उसे एक नज़र रखना चाहिए dog। से के बारे में HTTP आरएफसी303 :

यह विधि मुख्य रूप से एक चयनित संसाधन के लिए उपयोगकर्ता एजेंट को पुनर्निर्देशित करने के लिए एक POSTनिष्क्रिय स्क्रिप्ट के आउटपुट की अनुमति देने के लिए मौजूद है ।

यदि कार्य अतुल्यकालिक है, barkतो 1.2स्थिति की तरह ही एक सबस्रोत की आवश्यकता होती है और जब कार्य पूरा हो जाता है, तो 303उसे लौटा दिया जाना चाहिए GET .../barks/Y


3. छाल रिकॉर्डिंग के barkसाथ एक नया रिकॉर्ड बनाता है bark.timestampजब छाल ठीक हो जाती है। यह भी dog.barkCount1 से बढ़ा है।

POST /v1/dogs/1/barks HTTP/1.1
Host: api.animals.com
Authorization: Basic mAUhhuE08u724bh249a2xaP=

(document body, if needed)

201 Created
Location: http://api.animals.com/v1/dogs/1/barks/a65h44

यहां, barkअनुरोध के कारण बनाया गया है, इसलिए स्थिति 201 Createdलागू होती है।

यदि सृजन अतुल्यकालिक है, तो इसके बजाय एक 202 Acceptedआवश्यक है ( जैसा कि HTTP RFC कहता है )।

बचाया गया टाइमस्टैम्प barkसंसाधन का एक हिस्सा है और GETइसे इसके साथ पुनः प्राप्त किया जा सकता है। अद्यतन किए गए कुत्ते को उसी GET dogs/X/barks/Yरूप में "प्रलेखित" किया जा सकता है ।


4. छाल गितुब से कुत्ते कोड के नवीनतम संस्करण को खींचने के लिए एक सिस्टम कमांड चलाता है। यह तब dog.ownerउन्हें यह बताने के लिए एक पाठ संदेश भेजता है कि नया कुत्ता कोड उत्पादन में है।

इस एक का शब्दांकन जटिल है, लेकिन यह बहुत सरल है अतुल्यकालिक कार्य:

POST /v1/dogs/1/barks HTTP/1.1
Host: api.animals.com
Authorization: Basic mAUhhuE08u724bh249a2xaP=

(document body, if needed)

202 Accepted
Location: http://api.animals.com/v1/dogs/1/barks/a65h44

क्लाइंट तब वर्तमान स्थिति को जानने के GETलिए जारी करेगा /v1/dogs/1/barks/a65h44(यदि कोड खींचा गया था, तो यह ई-मेल स्वामी को भेजा गया था और ऐसे)। जब भी कुत्ता बदलता है, एक 303सराहनीय है।


समेट रहा हु

रॉय फील्डिंग का हवाला देते हुए :

REST के तरीकों की एकमात्र आवश्यकता यह है कि उन्हें सभी संसाधनों के लिए समान रूप से परिभाषित किया जाए (यानी, ताकि मध्यस्थों को अनुरोध के अर्थ को समझने के लिए संसाधन प्रकार का पता न चले)।

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

एक प्रोग्रामर को पता होगा: ए POSTसे barksपैदावार ए bark। प्रतिक्रिया स्थिति कोड (आवश्यक होने पर निकाय-निकाय और हेडर के साथ भी) यह समझाने का काम करते हैं कि ग्राहक क्या बदला और कैसे आगे बढ़ना चाहिए।

नोट: उपयोग किए जाने वाले प्राथमिक स्रोत थे: " रेस्टफुल वेब सर्विसेज " पुस्तक, HTTP RFC और रॉय फील्डिंग का ब्लॉग




संपादित करें:

सवाल और इस तरह जवाब काफी बदल गया है क्योंकि वे पहली बार बनाए गए थे। मूल प्रश्न यूआरआई तरह के डिजाइन के बारे में पूछा:

ACTION http://api.animals.com/v1/dogs/1/?action=bark

नीचे यह स्पष्टीकरण दिया गया है कि यह एक अच्छा विकल्प क्यों नहीं है:

क्लाइंट डेटा के साथ WHAT TO DO को कैसे बताते हैं, यह विधि की जानकारी है

  • Restful वेब सेवाएं HTTP मेथड में सूचना को बताती हैं।
  • विशिष्ट RPC- शैली और SOAP सेवाएँ इकाई-निकाय और HTTP शीर्ष लेख में अपना स्थान रखती हैं।

डेटा का हिस्सा [क्लाइंट को सर्वर चाहिए] जिस पर काम करना है, वह है स्कॉपिंग जानकारी

  • श्रेष्ठ सेवाएँ URI का उपयोग करती हैं। SOAP / RPC- शैली सेवाएँ एक बार फिर निकाय-निकाय और HTTP हेडर का उपयोग करती हैं।

एक उदाहरण के रूप में, Google का URI लें http://www.google.com/search?q=DOG। वहां, विधि की जानकारी है GETऔर स्कूपिंग जानकारी है /search?q=DOG

कहानी संक्षिप्त में:

  • में RESTful आर्किटेक्चर , विधि जानकारी HTTP विधि में चला जाता है।
  • में संसाधन उन्मुख आर्किटेक्चर , scoping जानकारी यूआरआई में चला जाता है।

और अंगूठे का नियम:

यदि HTTP विधि विधि की जानकारी से मेल नहीं खाती है, तो सेवा Restful नहीं है। यदि स्कोपिंग जानकारी URI में नहीं है, तो सेवा संसाधन-उन्मुख नहीं है।

आप "छाल" "क्रिया" को URL (या निकाय-निकाय) में डाल सकते हैं और उपयोग कर सकते हैं POST। वहाँ कोई समस्या नहीं है, यह काम करता है, और यह करने का सबसे सरल तरीका हो सकता है, लेकिन यह रेस्टफुल नहीं है

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

मैं आपकी विशिष्ट व्यावसायिक आवश्यकताओं के बारे में बात नहीं कर सकता, लेकिन मैं आपको एक उदाहरण देता हूं: एक RESTful ऑर्डरिंग सेवा पर विचार करें, जहां URI जैसे ऑर्डर हैं example.com/order/123

अब कहते हैं कि हम एक आदेश रद्द करना चाहते हैं, हम इसे कैसे करने जा रहे हैं? किसी को यह सोचने के लिए लुभाया जा सकता है कि यह "रद्द करना" "कार्रवाई" है और इसे डिजाइन करना POST example.com/order/123?do=cancel

यह Restful नहीं है, जैसा कि हमने ऊपर बात की है। इसके बजाय, हम भेजे गए तत्व PUTके orderसाथ एक नया प्रतिनिधित्व कर सकते हैं :canceledtrue

PUT /order/123 HTTP/1.1
Content-Type: application/xml

<order id="123">
    <customer id="89987">...</customer>
    <canceled>true</canceled>
    ...
</order>

और बस। यदि आदेश रद्द नहीं किया जा सकता है, तो एक विशिष्ट स्थिति कोड वापस किया जा सकता है। ( सादगी के लिए POST /order/123/canceledइकाई-निकाय के साथ एक सबसोर्स डिज़ाइन trueभी उपलब्ध हो सकता है।)

अपने विशिष्ट परिदृश्य में, आप कुछ इसी तरह की कोशिश कर सकते हैं। इस तरह से, जबकि एक कुत्ते भौंकने है, उदाहरण के लिए, एक GETपर /v1/dogs/1/है कि जानकारी शामिल हो सकते हैं (उदाहरण के लिए <barking>true</barking>) । या ... अगर वह बहुत जटिल है, तो अपनी आवश्यकता को पूरा करें और साथ रहें POST

अपडेट करें:

मैं उत्तर को बहुत बड़ा नहीं बनाना चाहता, लेकिन एक एल्गोरिथ्म (एक क्रिया ) को संसाधनों के एक समूह के रूप में उजागर करने के हैंग होने में थोड़ा समय लगता है । कार्यों के संदर्भ में सोचने के बजाय ( "मानचित्र पर स्थानों की खोज करें" ), किसी को उस कार्रवाई के परिणामों के बारे में सोचने की आवश्यकता है ( "खोज मानदंडों से मेल खाते मानचित्र पर स्थानों की सूची" )।

यदि आप पाते हैं कि आपका डिज़ाइन HTTP के एकसमान इंटरफ़ेस के अनुकूल नहीं है, तो आप अपने आप को इस चरण पर वापस आ सकते हैं।

क्वेरी चर जानकारी दे रहे हैं , लेकिन नए संसाधनों को निरूपित नहीं करते ( यह स्पष्ट रूप से एक ही संसाधन है , बस एक अलग प्रतिनिधित्व)। बल्कि, वे संप्रेषित करने के लिए उपयोग किया जाता है ग्राहक राज्य (जैसे ;, ताकि राज्य सर्वर में रखा नहीं है भी एक उदाहरण यहाँ है) या इनपुट पैरामीटर के लिए एल्गोरिथम संसाधनों ( , )। फिर, अलग संसाधन नहीं।/post?lang=en/post?lang=jp?page=10?lang=en/search?q=dogs/dogs?code=1

HTTP क्रिया '(विधियाँ) गुण:

एक अन्य स्पष्ट बिंदु जो ?action=somethingयूआरआई में प्रदर्शित होता है, रेस्टफुल नहीं है, HTTP क्रिया के गुण हैं:

  • GETऔर HEADसुरक्षित हैं (और बेकार);
  • PUTऔर DELETEकेवल बेरोजगार हैं;
  • POST नहीं है।

सुरक्षा : कुछ डेटा को पढ़ने के लिए अनुरोध GETया HEADअनुरोध , किसी सर्वर स्थिति को बदलने का अनुरोध नहीं है। ग्राहक 10 बार अनुरोध या अनुरोध कर सकता है और इसे एक बार बनाने के समान है, या इसे कभी भी नहीं बना सकता हैGETHEAD

Idempotence : एक में एक आदर्श ऑपरेशन, जिसका एक ही प्रभाव है कि क्या आप इसे एक बार या एक से अधिक बार लागू करते हैं (गणित में, शून्य से गुणा करना idempotent है)। यदि आप DELETEएक बार संसाधन करते हैं, तो फिर से हटाने का एक ही प्रभाव होगा (संसाधन GONEपहले से ही है)।

POSTन तो सुरक्षित है और न ही बेकार है। POST'फ़ैक्टरी' संसाधन के लिए दो समान अनुरोध करने से संभवतः दो अधीनस्थ संसाधनों में एक ही जानकारी होगी। अतिभारित (यूआरआई या इकाई-निकाय में विधि) के साथ POST, सभी दांव बंद हैं।

ये दोनों गुण HTTP प्रोटोकॉल (अविश्वसनीय नेटवर्क पर) की सफलता के लिए महत्वपूर्ण थे: आपने कितनी बार अपडेट किया है ( GET) पृष्ठ को प्रतीक्षा किए बिना जब तक यह पूरी तरह से लोड नहीं हो जाता?

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


मैं इस विचार के साथ विवाद करता हूं कि एक सर्वर पर एक कार्रवाई को कॉल करना, जिसे URL में एक कार्रवाई के रूप में नामित किया गया है, RESTful नहीं है। "डेटा का ब्लॉक प्रदान करने ... डेटा-हैंडलिंग प्रक्रिया केPOST लिए " के लिए डिज़ाइन किया गया था । ऐसा लगता है कि बहुत से लोग संसाधनों को कार्यों से अलग करते हैं, लेकिन वास्तव में क्रियाएँ केवल एक प्रकार का संसाधन हैं।
जैकब स्टीवंस

1
@JacobStevens ओपी ने सवाल को थोड़ा बदल दिया इसलिए मैंने इसे और अधिक प्रत्यक्ष बनाने के लिए अपने उत्तर को अपडेट किया ( मूल प्रश्न की जांच करें , शायद आप देखेंगे कि मेरा क्या मतलब है)। मैं POST"डेटा का एक ब्लॉक प्रदान करने ... डेटा-हैंडलिंग प्रक्रिया के लिए" से सहमत हूं , लेकिन अंतर वास्तव में है, डेटा का ब्लॉक, डेटा का ब्लॉक नहीं है और प्रक्रिया (कार्रवाई, विधि, कमांड) होना चाहिए उस पर अमल किया गया। यह POSTओवरलोडिंग है, और POSTओवरलोडिंग RPC- स्टाइल डिज़ाइन है, न कि Restful।
acccjunior

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

6
जवाब हमें अपडेट किया गया। यह थोड़ा लंबा है क्योंकि पूरी तरह से स्पष्टीकरण की आवश्यकता है ("ध्यान रखें कि मेरे पास RUD की एक अल्पविकसित समझ है।")। इसे यथासंभव पूर्ण बनाने के लिए एक संघर्ष की तरह था। आशा है कि यह किसी तरह से उपयोगी है।
22 अक्टूबर को acccjunior

2
महान स्पष्टीकरण, मैंने मतदान किया लेकिन 202 स्वीकार किए गए प्रतिक्रिया में स्थान शीर्षक का उपयोग नहीं किया जाना चाहिए। यह एक गलत व्याख्या है जो कई लोग RFC से करते हैं। इस चेक stackoverflow.com/questions/26199228/...
Delmo

6

मैंने पहले उत्तर दिया था , लेकिन यह उत्तर मेरे पुराने उत्तर का खंडन करता है और समाधान के लिए आने के लिए बहुत अलग रणनीति का अनुसरण करता है। यह दिखाता है कि HTTP अनुरोध REST और HTTP को परिभाषित करने वाली अवधारणाओं से कैसे बनाया गया है। यह भी के PATCHबजाय का उपयोग करता है POSTया PUT

यह REST बाधाओं, फिर HTTP के घटकों, फिर एक संभावित समाधान से गुजरता है।

आराम

आरएएसटी एक ऐसी कमी का एक सेट है जिसका उद्देश्य इसे वितरित करने के लिए वितरित हाइपरमीडिया प्रणाली पर लागू किया जाना है। यहां तक ​​कि किसी कार्रवाई को दूरस्थ रूप से नियंत्रित करने के संदर्भ में इसका अर्थ निकालने के लिए, आपको दूरस्थ रूप से वितरित हाइपरमीडिया प्रणाली के एक भाग के रूप में एक कार्रवाई को नियंत्रित करने के बारे में सोचना होगा - इंटरकनेक्शन जानकारी की खोज, देखने और संशोधित करने के लिए एक प्रणाली का एक हिस्सा। यदि यह इसके लायक होने से अधिक परेशानी है, तो शायद इसे RESTful बनाने की कोशिश करना अच्छा नहीं है। यदि आप क्लाइंट पर "कंट्रोल पैनल" टाइप GUI चाहते हैं, जो पोर्ट 80 के माध्यम से सर्वर पर कार्रवाई को ट्रिगर कर सकता है, तो आप संभवतः HTTP अनुरोधों / प्रतिक्रियाओं या एक WebSocket के माध्यम से JSON-RPC जैसा एक सरल RPC इंटरफ़ेस चाहते हैं।

लेकिन REST सोच का एक आकर्षक तरीका है और प्रश्न में उदाहरण एक RESTful इंटरफ़ेस के साथ मॉडल करना आसान होता है, तो चलिए मज़े के लिए और शिक्षा के लिए चुनौती लेते हैं।

REST को चार इंटरफ़ेस बाधाओं द्वारा परिभाषित किया गया है:

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

आप पूछते हैं कि आप इन बाधाओं को पूरा करते हुए एक इंटरफेस को कैसे परिभाषित कर सकते हैं, जिसके माध्यम से एक कंप्यूटर दूसरे कंप्यूटर को कुत्ते की छाल बनाने के लिए कहता है। विशेष रूप से, आप चाहते हैं कि आपका इंटरफ़ेस HTTP हो, और आप उन सुविधाओं को त्यागना नहीं चाहते हैं जो HTTP RESTful का उपयोग तब करते हैं जब आप इच्छित रूप में उपयोग किए जाते हैं।

चलो पहले बाधा से शुरू करते हैं: संसाधन पहचान

कोई भी जानकारी जिसे नाम दिया जा सकता है वह एक संसाधन हो सकता है: एक दस्तावेज या छवि, एक अस्थायी सेवा (जैसे "लॉस एंजिल्स में आज का मौसम"), अन्य संसाधनों का संग्रह, एक गैर-आभासी वस्तु (जैसे एक व्यक्ति), और इसी तरह ।

तो एक कुत्ता एक संसाधन है। इसे पहचानने की जरूरत है।

अधिक सटीक रूप से, एक संसाधन R एक अस्थायी रूप से बदलती सदस्यता फ़ंक्शन M R ( t ) है, जो समय टी नक्शे के लिए संस्थाओं, या मूल्यों के एक सेट के लिए है, जो समकक्ष हैं। सेट में मान संसाधन प्रतिनिधित्व और / या संसाधन पहचानकर्ता हो सकते हैं

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

REST घटक उस संसाधन की वर्तमान या इच्छित स्थिति पर कब्जा करने और घटकों के बीच उस प्रतिनिधित्व को स्थानांतरित करने के लिए एक प्रतिनिधित्व का उपयोग करके संसाधन पर कार्य करते हैं। एक प्रतिनिधित्व बाइट्स का एक क्रम है, साथ ही उन बाइट्स का वर्णन करने के लिए मेटाडेटा का प्रतिनिधित्व करता है।

निम्नलिखित बाइट्स का एक क्रम कुत्ते की इच्छित स्थिति को कैप्चर करना है, अर्थात हम जिस पहचानकर्ता को "डॉग # 1" से जोड़ना चाहते हैं (ध्यान दें कि यह केवल राज्य के हिस्से का प्रतिनिधित्व करता है क्योंकि यह कुत्ते के नाम, स्वास्थ्य का सम्मान नहीं करता है , या यहां तक ​​कि पिछले छाल):

यह 10 मिनट हर बार भौंकने के बाद से इस राज्य परिवर्तन को प्रभावित किया गया था, और अनिश्चित काल तक जारी रहेगा।

यह मेटाडेटा से जुड़ा होना चाहिए जो इसका वर्णन करता है। यह मेटाडेटा उपयोगी हो सकता है:

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

अंत में, चौथे बाधा को देखें: HATEOAS

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

Restful इंटरफ़ेस में, क्लाइंट को यह पता लगाने के लिए कि उसे कैसे प्राप्त करना चाहिए या एक प्रतिनिधित्व भेजना चाहिए, संसाधन प्रतिनिधित्व प्राप्त करता है। आवेदन में कहीं न कहीं एक निरूपण होना चाहिए जिससे ग्राहक यह पता लगा सके कि सभी अभ्यावेदन प्राप्त करने या भेजने के लिए इसे प्राप्त करने या भेजने में सक्षम होना चाहिए, भले ही वह उस सूचना पर पहुंचने के लिए अभ्यावेदन की एक श्रृंखला का पालन करता हो। यह काफी सरल लगता है:

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

एचटीटीपी

HTTP अनुवर्ती नियम निम्न प्रकार से लागू करता है:

संसाधन पहचान : URI

संसाधन प्रतिनिधित्व : निकाय-निकाय

स्व-विवरण : विधि या स्थिति कोड, शीर्षलेख, और संभवतः निकाय-निकाय के कुछ भाग (जैसे XML स्कीमा का URI)

HATEOAS : हाइपरलिंक

आपने http://api.animals.com/v1/dogs/1URI के रूप में निर्णय लिया है । चलो मान लेते हैं कि ग्राहक को साइट पर किसी पृष्ठ से यह मिला है।

आइए इस इकाई-निकाय का उपयोग करें (मान का nextटाइमस्टैम्प है; 0इसका अर्थ है 'जब यह अनुरोध प्राप्त होता है'):

{"barks": {"next": 0, "frequency": 10}}

अब हमें एक विधि की आवश्यकता है। PATCH ने हमारे द्वारा तय किए गए "इच्छित राज्य का हिस्सा" विवरण फिट किया:

PATCH विधि अनुरोध करती है कि अनुरोध इकाई में वर्णित परिवर्तनों का एक सेट अनुरोध-यूआरआई द्वारा पहचाने गए संसाधन पर लागू हो।

और कुछ हेडर:

इकाई-निकाय की भाषा को इंगित करने के लिए: Content-Type: application/json

यह सुनिश्चित करने के लिए कि यह केवल एक बार होता है: If-Unmodified-Since: <date/time this was first sent>

और हमारे पास एक अनुरोध है:

PATCH /v1/dogs/1/ HTTP/1.1
Host: api.animals.com
Content-Type: application/json
If-Unmodified-Since: <date/time this was first sent>
[other headers]

{"barks": {"next": 0, "frequency": 10}}

सफलता पर, ग्राहक को 204प्रतिक्रिया में एक स्टेटस कोड प्राप्त करना चाहिए , या 205यदि /v1/dogs/1/नए बार्किंग शेड्यूल को प्रतिबिंबित करने के लिए प्रतिनिधित्व बदल गया है।

असफलता पर, यह एक 403और एक उपयोगी संदेश क्यों प्राप्त करना चाहिए ।

जवाब में एक प्रतिनिधित्व में छाल अनुसूची को प्रतिबिंबित करने के लिए सेवा के लिए आरईएसटी को लागू करना आवश्यक नहीं है GET /v1/dogs/1/, लेकिन यह सबसे अधिक समझ में आता है अगर एक JSON प्रतिनिधित्व इसमें शामिल है:

"barks": {
    "previous": [x_1, x_2, ..., x_n],
    "next": x_n,
    "frequency": 10
}

क्रोन नौकरी को एक कार्यान्वयन विवरण के रूप में समझें कि सर्वर इंटरफ़ेस से छुपाता है। यह एक सामान्य इंटरफ़ेस की सुंदरता है। क्लाइंट को यह जानने की ज़रूरत नहीं है कि सर्वर पर्दे के पीछे क्या करता है; सभी यह परवाह करते हैं कि सेवा अनुरोधित राज्य परिवर्तनों को समझती है और प्रतिक्रिया देती है।


3

अधिकांश लोग इस उद्देश्य के लिए POST का उपयोग करते हैं । जब कोई अन्य HTTP विधि उपयुक्त नहीं लगती है तो "किसी भी असुरक्षित या गैर-सरकारी ऑपरेशन को करने के लिए उपयुक्त है"।

XMLRPC जैसे एपीआई उन कार्यों को ट्रिगर करने के लिए POST का उपयोग करते हैं जो मनमाना कोड चला सकते हैं। "कार्रवाई" POST डेटा में शामिल है:

POST /RPC2 HTTP/1.0
User-Agent: Frontier/5.1.2 (WinNT)
Host: betty.userland.com
Content-Type: text/xml
Content-length: 181

<?xml version="1.0"?>
<methodCall>
   <methodName>examples.getStateName</methodName>
   <params>
      <param>
         <value><i4>41</i4></value>
         </param>
      </params>
   </methodCall>

RPC का उदाहरण यह दिखाने के लिए दिया गया है कि POST सर्वर-साइड विधियों के लिए HTTP क्रियाओं का पारंपरिक विकल्प है। यहाँ रॉय पोस्टिंग के बारे में विचार कर रहे हैं - वह बहुत कहते हैं कि यह HTTP विधियों का उपयोग के रूप में निर्दिष्ट है।

ध्यान दें कि RPC खुद बहुत Restful नहीं है क्योंकि यह संसाधन उन्मुख नहीं है। लेकिन अगर आपको स्टेटलेसनेस, कैशिंग, या लेयरिंग की आवश्यकता है, तो उचित परिवर्तन करना मुश्किल नहीं है। एक उदाहरण के लिए http://blog.perfectapi.com/2012/opinionated-rpc-apis-vs-restful-apis/ देखें ।


मुझे लगता है कि आप इसे क्वेरी स्ट्रिंग में नहीं डालेंगे, जैसे कि टेम्कोड्स को URLencode
tacos_tacos_tacos

@ किर्क हाँ, लेकिन एक मामूली संशोधन के साथ, अंतिम फ़ॉरवर्ड स्लैश छोड़ें: POST api.animals.com/v1/dogs1?action=bark
रेमंड हेटिंगर

यदि आप इस उत्तर में सलाह का पालन करते हैं, तो ध्यान रखें कि परिणामी API RESTful नहीं होगा।
निकोलस शैंक्स

2
यह RESTful नहीं है क्योंकि HTTP URL को एक संसाधन की पहचानकर्ता के रूप में स्थापित करता है और एक URL /RPC2एक संसाधन की पहचान करने के लिए कुछ नहीं करता है - यह एक सर्वर तकनीक की पहचान करता है। इसके बजाय, यह methodName'संसाधन' की 'पहचान' करने की कोशिश करता है - लेकिन फिर भी, यह संज्ञा / क्रिया भेद से लाभ नहीं उठाता है; यहाँ केवल 'क्रिया' जैसी चीज़ है methodCall। यह 'स्टेट-नेम-रि-नेम' की जगह 'डू-स्टेट-नेम-रिट्रीवल' जैसा है - बाद वाला इतना अधिक समझ में आता है।
जॉर्डन

लिंक के लिए +1; बहुत जानकारीपूर्ण और "राय RPC" प्रयोग आविष्कारशील है।
जॉर्डन

2

POSTके लिए बनाया गया HTTP तरीका है

डेटा का एक ब्लॉक प्रदान करना ... डेटा-हैंडलिंग प्रक्रिया के लिए

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

उस ने कहा, अपने कुत्ते के भौंकने के परिदृश्य में, यदि आप चाहते हैं कि हर 10 मिनट में एक सर्वर-साइड छाल का प्रदर्शन किया जाए, लेकिन किसी कारण से एक क्लाइंट से उत्पन्न होने के लिए ट्रिगर की आवश्यकता होती है, PUTतो इसका उद्देश्य बेहतर सेवा प्रदान करना होगा, क्योंकि यह अपने आदर्श के कारण है। खैर, इस परिदृश्य से कड़ाई से कई POST अनुरोधों का कोई स्पष्ट जोखिम नहीं है, जिसके कारण आपका कुत्ता म्याऊ कर रहा है, लेकिन वैसे भी यह दो समान तरीकों का उद्देश्य है। एक समान SO प्रश्न के लिए मेरा उत्तर आपके लिए उपयोगी हो सकता है।


1
PUT बनाम POST सभी URL के बारे में है। 9.6 PUT के बाद तीसरा पैराग्राफ कहता है कि दो विधियों का उद्देश्य है, इसलिए PUTURL का तात्पर्य है कि ग्राहक की सामग्री से क्या बदला जाना चाहिए और POSTURL से तात्पर्य है कि ग्राहक की सामग्री को संसाधित करना चाहिए , हालांकि यह चाहता है।
जॉर्डन

1

अगर हम मानते हैं कि बार्किंग एक आंतरिक / निर्भर / उप संसाधन है जिस पर उपभोक्ता कार्य कर सकता है, तो हम कह सकते हैं:

POST http://api.animals.com/v1/dogs/1/bark

कुत्ते की संख्या 1 छाल

GET http://api.animals.com/v1/dogs/1/bark

अंतिम छाल टाइमस्टैम्प लौटाता है

DELETE http://api.animals.com/v1/dogs/1/bark

लागू नहीं होता है! इसलिए इसे अनदेखा करें।


यह केवल RESTful है यदि आप प्रति/v1/dogs/1/bark संसाधन संसाधन मानते हैं , और यह वर्णन करने के लिए कि संसाधन की आंतरिक स्थिति कैसे बदलनी चाहिए। मुझे लगता है कि यह सिर्फ एक संसाधन के रूप में विचार करने और इकाई-निकाय में यह संकेत देने के लिए अधिक समझ में आता है कि इसे छाल करना चाहिए। POST/v1/dogs/1/
जॉर्डन

mmm .. अच्छा, यह एक संसाधन है जिसे आप अपनी स्थिति बदल सकते हैं। क्योंकि उसके राज्य को बदलने का परिणाम शोर कर रहा है, यह कम संसाधन नहीं बनाता है! आप बार्क को एक क्रिया के रूप में देख रहे हैं (जो है) इसीलिए आप इसे संसाधन नहीं मान सकते। मैं इसे एक आश्रित संसाधन के रूप में देख रहा हूं जिसे इसका राज्य बदला जा सकता है और चूँकि इसका राज्य बुलियन है, इसलिए मुझे इकाई-निकाय में इसका उल्लेख करने का कोई कारण नहीं दिखता है। यह सिर्फ मेरी राय है।
बोल

1

कुछ उत्तरों के पहले के संशोधन से आपको आरपीसी का उपयोग करने का सुझाव दिया गया है। आपको RPC को देखने की आवश्यकता नहीं है क्योंकि ऐसा करना पूरी तरह से संभव है कि आप REST बाधाओं का पालन करना चाहते हैं।

सबसे पहले, URL में एक्शन पैरामीटर न रखें। URL परिभाषित करता है कि आप क्या कार्रवाई कर रहे हैं और क्वेरी पैरामीटर URL का हिस्सा हैं। इसे पूरी तरह से एक संज्ञा के रूप में सोचा जाना चाहिए http://api.animals.com/v1/dogs/1/?action=barkएक अलग संसाधन है - एक अलग संज्ञा - से http://api.animals.com/v1/dogs/1/। [nb आस्कर ने ?action=barkURI को प्रश्न से हटा दिया है ।] उदाहरण के लिए, तुलना http://api.animals.com/v1/dogs/?id=1करें http://api.animals.com/v1/dogs/?id=2। विभिन्न संसाधनों, केवल क्वेरी स्ट्रिंग द्वारा प्रतिष्ठित। इसलिए आपके अनुरोध की कार्रवाई, जब तक कि यह सीधे शरीर-रहित मौजूदा विधि प्रकार (TRACE, OPTIONS, HEAD, GET, DELETE, आदि) से मेल खाती है, तब तक अनुरोध निकाय में परिभाषित नहीं किया जाना चाहिए।

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

इम्पोटेंट का मतलब है कि परिणाम को बदले बिना एक अनुरोध दोहराया जा सकता है इन प्रभावों में लॉगिंग और ऐसे अन्य सर्वर व्यवस्थापक गतिविधि शामिल नहीं हैं। अपने पहले और दूसरे उदाहरणों का उपयोग करते हुए, एक ही व्यक्ति को दो ईमेल भेजने का परिणाम एक ईमेल भेजने की तुलना में एक अलग स्थिति में होता है (प्राप्तकर्ता के पास दो इनबॉक्स हैं, जिसे वे स्पैम मान सकते हैं), इसलिए मैं निश्चित रूप से उसके लिए POST का उपयोग करूंगा । यदि उदाहरण 2 में barkCount का इरादा आपके API के उपयोगकर्ता द्वारा देखा जाना है या ग्राहक-दृश्य में दिखाई देने वाली किसी चीज़ को प्रभावित करता है, तो यह कुछ ऐसा भी है जो अनुरोध को गैर-बेरोजगार बना देगा। यदि यह केवल आपके द्वारा देखा जाना है, तो यह सर्वर लॉगिंग के रूप में गिना जाता है और idempotentcy निर्धारित करते समय इसे अनदेखा किया जाना चाहिए।

अंत में, यह निर्धारित करें कि आप जो कार्य करना चाहते हैं, वह तुरंत सफल होने की उम्मीद कर सकता है या नहीं। बार्कडॉग एक जल्दी पूरी होने वाली क्रिया है। RunMarathon नहीं है। यदि आपकी क्रिया धीमी है, 202 Acceptedतो प्रतिक्रिया के लिए एक निकाय के URL के साथ, किसी उपयोगकर्ता के लिए यह देखने के लिए चुनाव करें कि क्या कार्रवाई पूर्ण है। वैकल्पिक रूप से, उपयोगकर्ताओं को सूची URL जैसे POST /marathons-in-progress/और फिर जब कार्रवाई की जाती है, तो उन्हें प्रगति आईडी URL से URL पर पुनर्निर्देशित /marathons-complete/करें।
# 1 और # 2 के विशिष्ट मामलों के लिए, मेरे पास सर्वर को एक कतार में होस्ट करना होगा, और उसके पते के क्लाइंट पोस्ट बैच होंगे। कार्रवाई SendEmails नहीं होगी, लेकिन कुछ AddToDispatchQueue की तरह। सर्वर तब कतार को प्रदूषित कर सकता है यह देखने के लिए कि क्या कोई ईमेल पते प्रतीक्षा कर रहे हैं, और यदि कोई मिलता है तो ईमेल भेजें। इसके बाद यह इंगित करने के लिए कतार अपडेट होती है कि लंबित कार्रवाई अब की गई है। आपके पास एक और URI होगा जो ग्राहक को कतार की वर्तमान स्थिति दिखाएगा। ईमेल के दोहरे-भेजने से बचने के लिए, सर्वर यह भी लॉग रख सकता है कि यह ईमेल किसने भेजा है, और प्रत्येक पते की जांच करें ताकि यह सुनिश्चित हो सके कि यह कभी भी एक ही पते पर दो नहीं भेजता है, भले ही आप एक ही सूची को दो बार पोस्ट करें। कतार।

किसी भी चीज़ के लिए URI चुनते समय, उसे एक परिणाम के रूप में सोचने की कोशिश करें, न कि एक क्रिया के रूप में। उदाहरण के लिए "कुत्ते" शब्द के लिए खोज google.com/search?q=dogsके परिणाम दिखाता है । यह खोज करने की आवश्यकता नहीं है।

आपकी सूची से # 3 और # 4 के मामले भी बेकार की कार्रवाई नहीं हैं। आप सुझाव देते हैं कि विभिन्न सुझाए गए प्रभाव एपीआई डिजाइन को प्रभावित कर सकते हैं। सभी चार मामलों में मैं एक ही एपीआई का उपयोग करूँगा, क्योंकि सभी चार "विश्व स्थिति" को बदलते हैं।


मान लीजिए कि कार्रवाई एक विशाल ईमेल कतार के माध्यम से मंथन करने और लोगों के एक समूह को एक संदेश भेजने के लिए है। क्या वह मूर्ख है? क्या PUT या POST के लिए उदासीन कार्य हैं?
कर्क उइमित

@kirk मैंने अपने उत्तर का विस्तार किया है।
निकोलस शैंक्स

0

मेरा नया उत्तर देखें - यह इस का खंडन करता है और REST और HTTP को अधिक स्पष्ट और सटीक रूप से समझाता है।

यहाँ एक सिफारिश है कि RESTful होने के लिए होता है, लेकिन निश्चित रूप से एकमात्र विकल्प नहीं है। सेवा के अनुरोध प्राप्त होने पर भौंकना शुरू करने के लिए:

POST /v1/dogs/1/bark-schedule HTTP/1.1
...
{"token": 12345, "next": 0, "frequency": 10}

token एक मनमाना संख्या है जो निरर्थक छालों को रोकता है चाहे कितनी बार यह अनुरोध भेजा गया हो।

nextअगले छाल के समय को इंगित करता है; 0'ASAP' का अर्थ है मूल्य ।

जब भी आप GET /v1/dogs/1/bark-schedule, आप कुछ इस तरह मिलना चाहिए, जहां टी पिछले छाल का समय आ गया है और यू है टी + 10 मिनट:

{"last": t, "next": u}

मैं अत्यधिक अनुशंसा करता हूं कि आप उसी URL का उपयोग छाल का अनुरोध करने के लिए करें जिसका उपयोग आप कुत्ते की वर्तमान भौंकने की स्थिति के बारे में पता लगाने के लिए करते हैं। यह REST के लिए आवश्यक नहीं है, लेकिन यह शेड्यूल को संशोधित करने के कार्य पर जोर देता है।

उपयुक्त स्थिति कोड शायद 205 है । मैं एक क्लाइंट की कल्पना कर रहा हूं जो वर्तमान शेड्यूल को देखता POSTहै, इसे बदलने के लिए उसी URL पर जाता है, और सेवा द्वारा निर्देश दिया जाता है कि शेड्यूल को दूसरा रूप देने के लिए यह साबित करें कि इसे बदल दिया गया है।

व्याख्या

आराम

एक पल के लिए HTTP के बारे में भूल जाओ। यह समझना आवश्यक है कि एक संसाधन एक फ़ंक्शन है जो इनपुट के रूप में समय लेता है और एक सेट प्रदान करता है जिसमें पहचानकर्ता और प्रतिनिधित्व होते हैं । के आसान बनाने कि लिए करते हैं: एक संसाधन एक सेट है आर पहचानकर्ता और अभ्यावेदन की; R बदल सकता है - सदस्यों को जोड़ा, हटाया या संशोधित किया जा सकता है। (यह बुरा है, अस्थिर डिजाइन हटाने या पहचानकर्ता संशोधित करते हैं। करने के लिए हालांकि) हम एक पहचानकर्ता का एक तत्व है कि कहते हैं कि आर की पहचान करता है आर , और एक प्रतिनिधित्व का एक तत्व है कि कि आर का प्रतिनिधित्व करता है आर

मान लीजिए कि आर एक कुत्ता है। आप आर की पहचान करते हैं /v1/dogs/1। (मतलब R/v1/dogs/1 का एक सदस्य है ।) आर को पहचानने के कई तरीकों में से एक है । आप R को और जैसे भी पहचान सकते हैं ।/v1/dogs/1/x-rays/v1/rufus

आप R का प्रतिनिधित्व कैसे करते हैं ? शायद एक तस्वीर के साथ। शायद एक्स-रे के सेट के साथ। या शायद तारीख और समय के संकेत के साथ जब आर आखिरी बार भौंकता है। लेकिन याद रखें कि ये सभी एक ही संसाधन के प्रतिनिधित्व हैं । /v1/dogs/1/x-raysउसी संसाधन का एक पहचानकर्ता है जो प्रश्न के उत्तर द्वारा " आर आखिरी छाल कब किया ?"

एचटीटीपी

यदि आप चाहते हैं, तो किसी संसाधन का एकाधिक प्रतिनिधित्व बहुत उपयोगी नहीं है। इसीलिए HTTP उपयोगी है: यह आपको पहचानकर्ताओं को अभ्यावेदन से जोड़ने की सुविधा देता है । यही है, यह सेवा के लिए एक यूआरएल प्राप्त करने और ग्राहक को सेवा करने के लिए कौन सा प्रतिनिधित्व तय करने का एक तरीका है।

कम से कम, कि क्या GETकरता है। PUTमूल रूप से का उल्टा होता है GETआप: PUTएक प्रतिनिधित्व आर यदि आप भविष्य के लिए इच्छा URL पर GETजो URL से अनुरोध वापस जाने के लिए आर , एचटीएमएल को JSON जैसे कुछ संभव अनुवाद के साथ।

POSTएक प्रतिनिधित्व को संशोधित करने का एक शिथिल तरीका है। प्रदर्शन तर्क और संशोधन तर्क होने के बारे में सोचें जो एक दूसरे के समकक्ष हैं - दोनों एक ही URL के अनुरूप हैं। POST अनुरोध सूचना को संसाधित करने और किसी भी अभ्यावेदन (न केवल एक ही URL द्वारा स्थित प्रतिनिधित्व) को संशोधित करने के लिए संशोधन तर्क के लिए एक अनुरोध है क्योंकि सेवा फिट दिखती है। 9.6 PUT के बाद तीसरे पैराग्राफ पर ध्यान दें : आप URL पर नई सामग्री की जगह नहीं ले रहे हैं; आप कुछ जानकारी संसाधित करने के लिए URL पर बात पूछ रहे हैं और समझदारी से निरूपण के रूप में प्रतिक्रिया दे रहे हैं।

हमारे मामले में, हम /v1/dogs/1/bark-scheduleअपनी जानकारी को संसाधित करने और उसके अनुसार कुछ निरूपणों को संशोधित करने के लिए संशोधन तर्क पूछते हैं (जो कि प्रदर्शन तर्क का प्रतिपक्ष है जो हमें बताता है कि यह अंतिम बार कब छाल गया और कब अगली छाल करेगा)। भविष्य के GETएस के जवाब में , उसी URL के अनुरूप प्रदर्शन तर्क हमें बताएगा कि कुत्ता अब हमारी इच्छानुसार भौंक रहा है।

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


-1

REST एक संसाधन उन्मुख मानक है, यह एक RPC होगी के रूप में संचालित कार्रवाई नहीं है।

आप के लिए अपने सर्वर चाहते हैं छाल , आप की तरह अलग अलग विचारों पर गौर करना चाहिए JSON-RPC या WebSockets संचार में,।

इसे बनाए रखने का हर प्रयास मेरे विचार में Restful विफल होगा: आप पैरामीटर के POSTसाथ जारी कर सकते actionहैं, आप कोई नया संसाधन नहीं बना रहे हैं, लेकिन जैसा कि आपके दुष्प्रभाव हो सकते हैं, आप अधिक सुरक्षित हैं।


POST"डेटा का ब्लॉक प्रदान करने ... डेटा-हैंडलिंग प्रक्रिया के लिए " के लिए डिज़ाइन किया गया था । ऐसा लगता है कि बहुत से लोग संसाधनों को कार्यों से अलग करते हैं, लेकिन वास्तव में क्रियाएँ केवल एक प्रकार का संसाधन हैं। एक सर्वर पर एक एक्शन रिसोर्स को कॉल करना अभी भी एक समान इंटरफ़ेस, कैचेबल, मॉड्यूलर और स्केलेबल है। यह भी स्टेटलेस है, लेकिन इसका उल्लंघन हो सकता है यदि क्लाइंट से प्रतिक्रिया की उम्मीद करने के लिए डिज़ाइन किया गया हो। लेकिन सर्वर पर एक "शून्य विधि" को कॉल करना , जो रॉय फील्डिंग रीस्ट के साथ करना है
याकूब स्टीवंस

जैसा कि मैंने अपने उत्तर में वर्णन किया है , आप REST में स्पष्ट रूप से सर्वर को यह कहकर कार्रवाई करने का कारण बन सकते हैं, कि अब से, "आपकी कार्रवाई पूरी हो गई", जबकि RPC सर्वर के प्रदर्शन के लिए पूछने के विचार पर आधारित है कार्य। दोनों ही सही अर्थ रखते हैं, जैसे कि अनिवार्य और घोषणात्मक प्रोग्रामिंग दोनों समझ में आते हैं।
जॉर्डन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.