RESTful API: HTTP साझा या विशिष्ट URL के साथ क्रिया करता है?


25

RESTful API बनाते समय , क्या मुझे उसी URL पर HTTP Verbs का उपयोग करना चाहिए (जब यह संभव हो) या क्या मुझे प्रति क्रिया के लिए एक विशिष्ट URL बनाना चाहिए?

उदाहरण के लिए:

GET     /items      # Read all items
GET     /items/:id  # Read one item
POST    /items      # Create a new item
PUT     /items/:id  # Update one item
DELETE  /items/:id  # Delete one item

या विशिष्ट URL जैसे:

GET     /items            # Read all items
GET     /item/:id         # Read one item
POST    /items/new        # Create a new item
PUT     /item/edit/:id    # Update one item
DELETE  /item/delete/:id  # Delete one item

जवाबों:


46

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

जरा देखिए DELETE /item/delete/:id, आप एक ही जानकारी को एक ही अनुरोध में दो बार देते हैं। यह शानदार है और इसे टाला जाना चाहिए। व्यक्तिगत रूप से, मैं इससे भ्रमित होऊंगा। क्या एपीआई वास्तव में DELETEअनुरोधों का समर्थन करता है? क्या होगा अगर मैं deleteURL में जगह और एक अलग HTTP क्रिया का उपयोग करें? क्या यह कुछ भी मैच करेगा? यदि हां, तो किसे चुना जाएगा? एक अच्छी तरह से डिज़ाइन किए गए API के ग्राहक के रूप में, मुझे इस तरह के सवाल नहीं पूछने चाहिए।

हो सकता है कि आपको किसी ऐसे क्लाइंट का समर्थन करने की आवश्यकता हो जो जारी DELETEया PUTअनुरोध नहीं कर सकता है । अगर ऐसा है, तो मैं इस जानकारी को एक HTTP हेडर में पास करूंगा। कुछ एपीआई X-HTTP-Method-Overrideइस विशिष्ट उद्देश्य के लिए एक हेडर का उपयोग करते हैं (जो मुझे लगता है कि वैसे भी काफी बदसूरत है)। मैं निश्चित रूप से हालांकि पथ में क्रिया जगह नहीं होगा।

के लिए जाओ

GET     /items      # Read all items
GET     /items/:id  # Read one item
POST    /items      # Create a new item
PUT     /items/:id  # Update one item
DELETE  /items/:id  # Delete one item

क्रियाओं के बारे में महत्वपूर्ण बात यह है कि वे पहले से ही HTTP विनिर्देशन में अच्छी तरह से परिभाषित हैं और इन नियमों के अनुरूप रहने से आप अपने एप्लिकेशन के लिए बाहरी कैश, प्रॉक्सी और संभवतः अन्य टूल का उपयोग कर सकते हैं जो HTTP के शब्दार्थ को समझते हैं लेकिन आपके आवेदन शब्दार्थ को नहीं समझते हैं । कृपया ध्यान दें कि आपके URL में उनके होने से बचने का कारण रीडेबल URL के लिए RESTful API के बारे में नहीं है। यह अनावश्यक अस्पष्टता से बचने के बारे में है।

क्या अधिक है, एक RESTful API इन क्रियाओं (या किसी भी उपसमुच्चय) को अनुप्रयोग शब्दार्थ के किसी भी सेट पर मैप कर सकता है, जब तक कि यह HTTP विनिर्देश के विरुद्ध नहीं जाता है। उदाहरण के लिए, एक RESTful API का निर्माण करना पूरी तरह से संभव है जो केवल GET अनुरोधों का उपयोग करता है यदि सभी ऑपरेशन जो इसे अनुमति देते हैं वे सुरक्षित और आदर्श दोनों हैं । उपरोक्त मानचित्रण केवल एक उदाहरण है जो आपके उपयोग के मामले में फिट बैठता है और कल्पना के अनुरूप है। जरूरी नहीं कि ऐसा हो ही।

कृपया यह भी ध्यान रखें कि वास्तव में RESTful API को प्रोग्रामर के लिए उपलब्ध URL के व्यापक प्रलेखन को पढ़ने के लिए कभी भी आवश्यकता नहीं होनी चाहिए क्योंकि आप HATEOAS (अनुप्रयोग राज्य के इंजन के रूप में हाइपरटेक्स्ट) के अनुरूप हैं, जो REST की मुख्य मान्यताओं में से एक है । जब तक ग्राहक एप्लिकेशन को समझ सकता है और उनका उपयोग कर सकता है, तब तक लिंक मानवों के लिए पूरी तरह से समझ से बाहर हो सकता है।


4
के अभाव में PUTऔर DELETE, मैं इसे पथ में जोड़ने का पक्ष लूंगा, इसे क्वेरी स्ट्रिंग के साथ विभेदित नहीं करने का। यह मौजूदा ऑपरेशन के लिए क्वेरी स्ट्रिंग संशोधन नहीं है; यह एक अलग ऑपरेशन है।
रॉबर्ट हार्वे

4
@RobertHarvey इस मामले में, मैं इसे वैसे भी हैक कहूंगा। जैसा कि आप कहते हैं, यह एक ऑपरेशन है और यह कुछ ऐसा नहीं है जिसे मैं एक डिज़ाइन करते समय रास्ते में डालूं जो कि RESTful हो। इसे क्वेरी स्ट्रिंग में रखने से कम आक्रामक लगता है। यह कैशिंग को रोकता है लेकिन मुझे नहीं लगता कि इस तरह के अनुरोधों पर प्रतिक्रियाएं वैसे भी कैश की जानी चाहिए। यह एपीआई के उपभोक्ता को यूआरएल को पार्स या निर्माण किए बिना आसानी से इंगित करने की अनुमति देता है। आदर्श रूप में, वास्तव में Restful API को स्वयं URL बनाने के लिए क्लाइंट की आवश्यकता के बिना हाइपरलिंक प्रदान करना चाहिए।
toniedzwiedz

यदि आपके पास सभी क्रियाएं नहीं हैं, तो यह पूरी तरह से Restful नहीं है, क्या यह है?
रॉबर्ट हार्वे

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

1
@RobertHarvey जैसा कि समझाया गया है, यह शायद ही उनका उपयोग करने का इच्छित तरीका है। जब आप ग्राहक सीमाओं को पार करना चाहते हैं तो मुझे यह दो बुराइयों का कम पता चलता है। मुझे ऐसे एपीआई के लिए एक दस्तावेज पढ़ना याद है, लेकिन मुझे इसे खोजने के लिए अपने ब्राउज़र इतिहास / बुकमार्क में कुछ खुदाई करनी होगी। अब जब मुझे लगता है कि, इस मामले में एक हेडर बेहतर हो सकता है। क्या आप सहमत हैं?
toniedzwiedz

14

पहले वाला।

एक URI / URL एक संसाधन पहचानकर्ता (नाम में संकेत: समान संसाधन पहचानकर्ता) है। पहले सम्मेलन के साथ, जब आप "GET / user / 123" करते हैं तो जिस संसाधन के बारे में बात की जाती है और "DELETE / user / 123" करते समय जिस संसाधन के बारे में बात की जाती है, वह स्पष्ट रूप से एक ही संसाधन होता है क्योंकि उनके पास एक ही URL होता है।

दूसरे सम्मेलन के साथ, आप यह सुनिश्चित नहीं कर सकते हैं कि "GET / user / 123" और "DELETE / user / delete / 123" वास्तव में एक ही संसाधन हैं, और इसका अर्थ यह है कि आप संसाधन के बजाय संबंधित संसाधन को हटा रहे हैं स्वयं, इसलिए यह /user/delete/123वास्तव में आश्चर्य की बात है कि हटाना वास्तव में हटा देता है /user/123। यदि आपके पास हर ऑपरेशन अलग-अलग URL पर काम करता है, तो URI अब संसाधन पहचानकर्ता के रूप में काम नहीं कर रहा है।

जब आप कहते हैं DELETE /user/123, आप कह रहे हैं "आईडी 123 के साथ उपयोगकर्ता का रिकॉर्ड हटाएं"। यदि आप कहते हैं DELETE /user/delete/123, तो आप जो लग रहे हैं , वह है 'डिलीट' यूजर डिलीट रिकॉर्ड को आईडी 123 'के साथ ", जो शायद आप कहना नहीं चाहते। और यहां तक ​​कि अगर आप इस स्थिति में अधिक सही क्रिया का उपयोग करते हैं: "POST / उपयोगकर्ता / हटाएं / 123" जो कहता है "ऑपरेशन को 'आईडी 123 के साथ उपयोगकर्ता विलोपक से जुड़ा हुआ है", यह अभी भी एक रिकॉर्ड हटाने के लिए कहने के लिए एक राउंडअबाउट तरीका है (यह अंग्रेजी में एक क्रिया की संज्ञा के समान है)।

URL के बारे में आप एक तरह से सोच सकते हैं कि यह ऑब्जेक्ट्स और रिसोर्स की तरह ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग में ऑब्जेक्ट्स की तरह ट्रीट करे। जब आप ऐसा करेंगे GET /user/123, DELETE /user/123:, आप वस्तु में तरीकों के रूप में उनमें से लगता है कि लगता है कि कर सकते हैं [/user/123].get(), [/user/123].delete()जहां []एक सूचक ऑपरेटर अपसंदर्भन की तरह लेकिन यूआरएल के लिए है (यदि आप है कि संकेत दिए गए एक भाषा जानते हैं)। REST के अंतर्निहित सिद्धांत में से एक समान इंटरफ़ेस है, जिसमें क्रियाओं / विधियों का एक छोटा और सीमित सेट है जो संसाधनों / वस्तुओं के विशाल नेटवर्क में सब कुछ के लिए काम करता है।

इसलिए, पहले वाला बेहतर है।

पुनश्च: बेशक, यह शुद्धतम तरीके से आरईएसटी को देख रहा है। कभी-कभी व्यावहारिकता शुद्धता को हरा देती है, और आपको ब्रेन-डेड क्लाइंट्स या फ्रेमवर्क के लिए रियायतें देने की जरूरत होती है, जिससे उचित रीस्ट करना कठिन हो जाता है।


OOP उदाहरण के लिए :) :)
53777A 7

6

(क्षमा करें, मेरे द्वारा पहली बार / संपादित / / और / / (2) को हटाने से ...)

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

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

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

इसलिए "/ आइटम / डिलीट / 123" REST को तोड़ता है क्योंकि यह एक संसाधन की ओर इशारा नहीं करता है, यह एक विधि आह्वान का अधिक है।

(इसके अलावा, सिर्फ शब्दार्थ, आपको एक URI प्राप्त करने में सक्षम होना चाहिए, यह तय करना पुराना है, और फिर उसी URI को DELETE करें - क्योंकि यह एक पहचानकर्ता है। यदि GET URI के पास "/ हटाएँ /" और DELETE नहीं है)। तब वह HTTP शब्दार्थ के विरुद्ध जाता है। आप प्रति संसाधन 2 या अधिक URI को प्रसारित कर रहे हैं जहाँ 1 करेंगे।)

अब, धोखा यह है: कोई वास्तविक स्पष्ट परिभाषा नहीं है कि क्या है और एक संसाधन नहीं है, इसलिए REST में आम चकमा एक "प्रसंस्करण संज्ञा" को परिभाषित करने और उस पर URI को इंगित करने के लिए है। यह एक शब्द का खेल है, लेकिन यह शब्दार्थ को संतुष्ट करता है।

इसलिए यदि, उदाहरण के लिए, आप वास्तव में किसी कारण से इसका उपयोग नहीं कर सकते हैं:

DELETE /items/123

आप दुनिया को "विलोपक" संसाधन संसाधन और उपयोग की घोषणा कर सकते हैं

POST /items/deletor  { id: 123 }

अब, यह RPC (दूरस्थ प्रक्रिया कॉल) की तरह दिखता है, लेकिन यह HTTP स्पेसिफिकेशन में नामित POST विनिर्देशन के "डेटा प्रोसेसिंग" क्लॉज के विशाल खामियों से गुजरता है।

हालाँकि, ऐसा करना असाधारण है, और यदि आप बनाने / अपडेट के लिए सामान्य PUT का उपयोग कर सकते हैं, डिलीट के लिए DELETE, और अपेंडेंट के लिए POST, बना सकते हैं, और बाकी सब कुछ, तो आपको चाहिए , क्योंकि यह HTTP का अधिक मानक उपयोग है। लेकिन अगर आपके पास "कमिटेड" या "पब्लिश" या "रीडैक्ट" जैसा कोई ट्रिकी केस है, तो प्रोसेसर संज्ञा का उपयोग करने का मामला REST शुद्धतावादियों को संतुष्ट करता है और फिर भी आपको आपके लिए आवश्यक शब्दार्थ प्रदान करता है।

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