HATEOAS: निरपेक्ष या सापेक्ष URL?


84

HATEOAS का उपयोग करके एक RESTful वेब सेवा को डिजाइन करने में, पूर्ण URL के रूप में एक लिंक दिखाने के पेशेवरों और विपक्ष क्या हैं (" http: // server: port / application / customers / 1234 ") बनाम पथ ("/ एप्लिकेशन /" ग्राहकों / 1234 ")?

जवाबों:


83

एक सूक्ष्म वैचारिक अस्पष्टता है जब लोग "रिश्तेदार यूआरआई" कहते हैं।

द्वारा RFC3986 की परिभाषा , एक सामान्य यूआरआई शामिल हैं:

  URI         = scheme ":" hier-part [ "?" query ] [ "#" fragment ]

  hier-part   = "//" authority path-abempty
              / path-absolute
              / path-rootless
              / path-empty

     foo://example.com:8042/over/there?name=ferret#nose
     \_/   \______________/\_________/ \_________/ \__/
      |           |            |            |        |
   scheme     authority       path        query   fragment

मुश्किल बात यह है कि, जब योजना और अधिकार छोड़े जाते हैं, तो "पथ" भाग या तो एक निरपेक्ष पथ हो सकता है (शुरू होता है /) या "मूल" सापेक्ष पथ। उदाहरण:

  1. एक पूर्ण यूआरआई या एक पूर्ण यूआरआई:"http://example.com:8042/over/there?name=ferret"
  2. और यह पूर्ण पथ के साथ एक रिश्तेदार उरी है :/over/there
  3. और यह एक है सापेक्ष URI, रिश्तेदार पथ के साथ : hereया ./hereया ../hereया आदि

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

और व्यवहार में, सबसे सर्वर साइड MVC ढांचे आसानी से उत्पन्न कर सकते हैं सापेक्ष URI निरपेक्ष पथ के साथ इस तरह के रूप /absolute/path/to/the/controller, और प्रश्न बन जाता है "कि सर्वर कार्यान्वयन एक उपसर्ग चाहिए scheme://hostname:portनिरपेक्ष पथ के सामने"। ओपी के सवाल की तरह। मैं इस बारे में निश्चित नहीं हूं।

एक ओर, मुझे अभी भी लगता है कि सर्वर एक पूर्ण यूरी लौटने की सिफारिश की है। हालाँकि, सर्वर को स्रोत कोड के अंदर की hostname:portचीज़ को कभी भी इस तरह से हार्डकोड नहीं करना चाहिए (अन्यथा मैं पूर्ण पथ के साथ संबंधित uri के लिए कमबैक करूंगा)। समाधान सर्वर-साइड है जो हमेशा HTTP अनुरोध के "होस्ट" हेडर से उस उपसर्ग को प्राप्त करता है। यह सुनिश्चित नहीं है कि यह हर स्थिति के लिए काम करता है या नहीं।

दूसरी ओर, ग्राहक के लिए http://example.com:8042और पूर्ण मार्ग को समाप्‍त करना बहुत कठिन नहीं लगता है। आखिरकार, क्लाइंट को पहले से ही उस स्कीम और डोमेन नाम का पता चल जाता है जब वह सर्वर को रिक्वेस्ट भेजता है?

सब के सब, मैं कहूंगा, निरपेक्ष यूआरआई का उपयोग करने की सलाह देते हैं, संभवतः निरपेक्ष पथ के साथ रिश्तेदार यूआरआई के लिए वापसी, कभी भी सापेक्ष पथ का उपयोग न करें


2
यह एक अच्छा उत्तर (+1) है जिसे मैं अंतिम निष्कर्ष को छोड़कर सहमत हूं। हालांकि मेरे जवाब में मेरा तर्क है कि HTTP कल्पना परिभाषित करती है, उदाहरण के लिए , "निरपेक्ष" एक पूर्ण पथ को संदर्भित करने के लिए, पूर्ण रूप से योग्य एनआरआई नहीं। यह - तो मैं के साथ अपने (2) असहमत है एक निरपेक्ष यूआरआई है जिसके लिए ग्राहक, नेटवर्क प्रोटोकॉल और होस्ट का अनुमान लगा होना चाहिए, तो यह पूरी तरह से योग्य यूआरआई नहीं है, लेकिन। और इसलिए, मैं भी (1) की अपनी परिभाषा है से असहमत दोनों एक पूर्ण यूआरआई और और निरपेक्ष यूआरआई।
लॉरेंस Dol

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

2
व्यावहारिक रूप से, मैं (2) के लिए हूं; मुझे लगता है कि (1) बैकएंड की आवश्यकता है बहुत HTTP विशिष्ट ज्ञान (विशिष्ट HTTP वातावरण के विवरण के बारे में अर्थ, सामान्य रूप से HTTP नहीं), और (3) क्लाइंट की बहुत अधिक आवश्यकता होती है। लेकिन , मेरा तर्क मूल ड्राफ्ट कल्पना पर आधारित था, और उदाहरणों को बाद के संस्करण में एक तरह से बदल दिया गया, जिससे मेरा तर्क अमान्य हो गया।
लॉरेंस Dol

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

@ लॉरेंसडॉल मुझे शुरुआत में HATEOAS के बारे में एक ही भ्रम है। अब मैं इसे पसंद का मामला मानता हूं। आपके ग्राहक निश्चित रूप से आपके एपीआई का उपभोग करने के लिए एडहॉक फ़ंक्शन का उपयोग कर सकते हैं, लेकिन यदि वे / आप चाहते हैं, तो वे / आप अभी भी उनके पालन के लिए एक पैटर्न विकसित कर सकते हैं, ताकि क्लाइंट को प्रत्येक सटीक यूआरएल को हार्ड कोड करने की आवश्यकता न हो। वह HATEOAS है।
रायलू

13

यह निर्भर करता है कि क्लाइंट कोड कौन लिख रहा है। यदि आप क्लाइंट और सर्वर लिख रहे हैं तो इससे बहुत फर्क नहीं पड़ता है। आप या तो क्लाइंट पर या सर्वर पर URL के निर्माण का दर्द झेलेंगे।

हालाँकि, यदि आप सर्वर का निर्माण कर रहे हैं और आप अन्य लोगों से क्लाइंट कोड लिखने की अपेक्षा करते हैं तो वे आपको अधिक पसंद करेंगे यदि आप पूरा यूआरआई प्रदान करते हैं। रिश्तेदार यूआरआई को हल करना थोड़ा मुश्किल हो सकता है। पहले आप उन्हें कैसे हल करते हैं यह मीडिया-प्रकार पर निर्भर करता है। Html का आधार टैग है, Xml में xml हो सकता है: प्रत्येक नेस्टेड तत्व में आधार टैग, Atom फीड में आधार और सामग्री में एक अलग आधार हो सकता है। यदि आप अपने ग्राहक को आधार यूआरआई के बारे में स्पष्ट जानकारी नहीं देते हैं, तो उन्हें आधार यूआरआई को अनुरोध यूआरआई से प्राप्त करना होगा, या शायद सामग्री-स्थान हेडर से! और उस अनुगामी स्लेश के लिए बाहर देखो। आधार URI अंतिम स्लैश के दाईं ओर सभी वर्णों को अनदेखा करके निर्धारित किया जाता है। इसका मतलब यह है कि रिश्तेदार URI का समाधान करते समय ट्रेलिंग स्लैश अब बहुत महत्वपूर्ण है।

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


11

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


7

आपके आवेदन के पैमानों के अनुसार, आप लोड बैलेंसिंग, फेल-ओवर इत्यादि करना चाह सकते हैं। यदि आप निरपेक्ष यूआरआई लौटाते हैं, तो आपके क्लाइंट-साइड ऐप आपके सर्वर के विकसित कॉन्फ़िगरेशन का पालन करेंगे।


बशर्ते आप "निरपेक्ष" को निरपेक्ष पथ (जैसे /xxx/yyy...) के रूप में परिभाषित करें और न कि पूरी तरह से योग्य यूआरआई (जैसे http://api.example.com/xxx/yyy...)।
लॉरेंस डॉल

6

रेलाउ के ट्राइकोटॉमी का उपयोग करके मेरे संगठन ने पक्षपात (2) का विकल्प चुना है। XSS (क्रॉस-साइट स्क्रिप्टिंग) हमलों से बचने के लिए प्राथमिक कारण है। मुद्दा यह है, अगर कोई हमलावर सर्वर से वापस आने वाली प्रतिक्रिया में अपने स्वयं के URL रूट को इंजेक्ट कर सकता है, तो बाद के उपयोगकर्ता अनुरोध (जैसे उपयोगकर्ता नाम और पासवर्ड के साथ प्रमाणीकरण अनुरोध) को हमलावर के स्वयं के सर्वर पर भेजा जा सकता है *।

कुछ लोगों ने लोड संतुलन के लिए अन्य सर्वरों के अनुरोधों को पुनर्निर्देशित करने में सक्षम होने का मुद्दा उठाया है, लेकिन (जबकि यह मेरी विशेषज्ञता का क्षेत्र नहीं है) मैं समझूंगा कि लोड संतुलन को स्पष्ट रूप से अलग करने के लिए क्लाइंट को अलग किए बिना लोड संतुलन को सक्षम करने के बेहतर तरीके हैं। मेजबान।

* कृपया मुझे बताएं कि क्या तर्क की इस पंक्ति में कोई दोष है। बेशक, लक्ष्य सभी हमलों को रोकने के लिए नहीं है, लेकिन हमले के कम से कम एक एवेन्यू।


खुशी है कि मेरा पिछला जवाब आपके संगठन के लिए मददगार था। हां, मैं व्यक्तिगत रूप से भी पसंद करता हूं (2), उर्फ ​​स्कीम-कम निरपेक्ष पथ। हालाँकि मैं आपके तर्क के बारे में उत्सुक हूँ। आपने अपने ग्राहक को केवल अपनी स्कीम-कम url स्वीकार करने के लिए कैसे लागू किया? एक जेनेरिक क्लाइंट, जैसे कि ब्राउज़र, स्कीम-कम यूआरएल को बिल्कुल भी अस्वीकार नहीं करेगा। इसलिए मुझे लगता है कि आपको वास्तव में उनका अनुसरण करने से पहले अपने स्वयं के क्लाइंट-साइड कोड को यूआरएल को मान्य करने के लिए लिखना होगा? हालांकि यह तकनीकी रूप से उल्लेखनीय है (लेकिन आवश्यक रूप से उपयोगी नहीं है), इस तरह की क्लाइंट-साइड मान्यता आमतौर पर REST या HATEOAS चर्चा का हिस्सा नहीं है।
रायलू

3
मुझे पता है कि यह एक पुरानी पोस्ट है, लेकिन मैं केवल यह बताना चाहता हूं कि "अगर कोई हमलावर वापस आने वाली प्रतिक्रिया में अपने स्वयं के URL रूट को इंजेक्ट कर सकता है " तो यह एक बकवास कारण है। यदि वे प्रतिक्रिया में "अपने स्वयं के URL" को सही स्थानों पर इंजेक्ट कर सकते हैं, तो मैं शर्त लगाता हूं कि वे आसानी से अपने होस्टनाम को आसानी से बदल सकते हैं। इसलिए सुरक्षा के दृष्टिकोण से, मैं इसे एक वैध तर्क के रूप में नहीं देखता हूं।
मैग्नस एरिकसन

5

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

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


1
खैर, स्थान हेडर के लिए HTTP कल्पना निरपेक्ष URI कहती है। एक पूर्ण यूआरआई में एक योजना (जैसे http) होनी चाहिए।
मार्क रॉबर्ट

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

क्या आप उस युक्ति के भाग को लिंक भेज सकते हैं जिसके बारे में आप बात कर रहे हैं?
मार्क रॉबर्ट

एक पूर्ण यूआरआई एक योजना निर्दिष्ट करता है; एक URI जो निरपेक्ष नहीं है उसे सापेक्ष कहा जाता है। URI को इस बात के अनुसार भी वर्गीकृत किया जाता है कि वे अपारदर्शी हैं या पदानुक्रमित। एक अपारदर्शी यूआरआई एक पूर्ण यूआरआई है जिसका योजना-विशिष्ट भाग स्लैश चरित्र ('/') से शुरू नहीं होता है। अपारदर्शी यूआरआई आगे पार्सिंग के अधीन नहीं हैं। अपारदर्शी यूआरआई के कुछ उदाहरण हैं: mailto: java-net@java.sun.com समाचार: comp.lang.java कलश: isbn: 096139210x
मार्क

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

2

बड़े एपीआई परिणामों में एक महत्वपूर्ण विचार बार-बार पूर्ण यूआरआई सहित अतिरिक्त नेटवर्क ओवरहेड है। मानो या न मानो, gzip इस मुद्दे को पूरी तरह से हल नहीं करता है (सुनिश्चित नहीं है कि क्यों)। हम इस बात से हैरान थे कि जब परिणाम में सैकड़ों लिंक शामिल थे तो पूरा यूआरआई कितना स्थान लेता था।


2

निरपेक्ष यूआरआई का उपयोग करने का एक दोष यह है कि एपी को अनुमानित नहीं किया जा सकता है।

इसे वापस ले लो ... सच नहीं है। आपको डोमेन सहित पूर्ण URL के लिए जाना चाहिए।


3
पूर्ण URI प्रॉक्सी के होस्टनाम का उपयोग क्यों नहीं कर सकता है?
एड समर्स

1
इस समय इस सटीक मुद्दे के माध्यम से काम करना। हम सभी अनुरोधों को पहले "लोड-बैलेंसिंग" परत के माध्यम से जाना चाहते हैं। सर्वरों को निरपेक्ष यूआरआई सीधे इस मॉडल को तोड़ देगा।
1338 पर mag382

1
मैं Nginx का उपयोग निरपेक्ष URL वाली साइट को प्रॉक्सी करने के लिए कर रहा हूँ। यह बराबर प्रॉक्सी URL के साथ बैकएंड URL को बदलने में पूरी तरह से सक्षम है। विशेष रूप से यह repo.windyroad.com.au के लिए windyroad.artifactoryonline.com (जिसमें पूरी तरह से योग्य URL और पूरी तरह से योग्य रीडायरेक्ट है) की जाँच कर रहा है
टॉम हावर्ड

2

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

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

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