rest - अनुरोध शरीर के साथ HTTP प्राप्त करें




http-get (12)

कौन सा सर्वर इसे अनदेखा करेगा? - फिजियारॉन 30 अगस्त '12 को 21:27 बजे

उदाहरण के लिए Google इसे अनदेखा करने से भी बदतर है, यह एक त्रुटि पर विचार करेगा!

इसे सरल नेटकैट के साथ आज़माएं:

$ netcat www.google.com 80
GET / HTTP/1.1
Host: www.google.com
Content-length: 6

1234

(1234 सामग्री सीआर-एलएफ द्वारा पीछा की जाती है, इसलिए यह कुल 6 बाइट्स है)

और आप पाएंगे:

HTTP/1.1 400 Bad Request
Server: GFE/2.0
(....)
Error 400 (Bad Request)
400. That’s an error.
Your client has issued a malformed or illegal request. That’s all we know.

आपको बिंग, ऐप्पल इत्यादि से 400 खराब अनुरोध भी मिलते हैं ... जो अकामाईगोस्ट द्वारा परोसा जाता है।

इसलिए मैं शरीर इकाई के साथ जीईटी अनुरोधों का उपयोग करने की सलाह नहीं दूंगा।

मैं अपने आवेदन के लिए एक नई रीस्टफुल webservice विकसित कर रहा हूँ।

कुछ संस्थाओं पर एक जीईटी करते समय, ग्राहक इकाई की सामग्री का अनुरोध कर सकते हैं। अगर वे कुछ पैरामीटर जोड़ना चाहते हैं (उदाहरण के लिए सूची को सॉर्ट करना) वे इन पैरामीटर को क्वेरी स्ट्रिंग में जोड़ सकते हैं।

वैकल्पिक रूप से मैं चाहता हूं कि लोग अनुरोध निकाय में इन मानकों को निर्दिष्ट करने में सक्षम हों। HTTP/1.1 स्पष्ट रूप से इसे मना नहीं करता है। इससे उन्हें अधिक जानकारी निर्दिष्ट करने की अनुमति मिल जाएगी, जटिल जटिल अनुरोधों को निर्दिष्ट करना आसान हो सकता है।

मेरे सवाल:

  • क्या यह एक अच्छा विचार है?
  • क्या HTTP क्लाइंट को GET अनुरोध के भीतर अनुरोध निकायों का उपयोग करने में समस्याएं होंगी?

HTTP/1.1


Elasticsearch एक शरीर के साथ अनुरोध प्राप्त स्वीकार करता है। ऐसा लगता है कि यह पसंदीदा तरीका है: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/common-options.html#_request_body_in_query_string

कुछ क्लाइंट लाइब्रेरीज़ (रूबी ड्राइवर की तरह) रोशन कमांड को विकास मोड में stdout पर लॉग कर सकते हैं और यह इस वाक्यविन्यास का व्यापक रूप से उपयोग कर रहा है।


XMLHttpRequest के अनुसार, यह मान्य नहीं है। standard :

4.5.6 send() विधि

client . send([body = null])

अनुरोध शुरू करता है। वैकल्पिक तर्क अनुरोध निकाय प्रदान करता है। अगर अनुरोध विधि GET या HEAD तो तर्क को अनदेखा किया जाता है।

अगर कोई राज्य खोला नहीं गया है या send() ध्वज सेट किया गया है तो एक InvalidStateError अपवाद फेंकता है।

send( body ) विधि को इन चरणों को चलाना चाहिए:

  1. अगर राज्य खोला नहीं गया है , तो एक InvalidStateError अपवाद फेंक दें।
  2. अगर send() ध्वज सेट किया गया है, तो एक InvalidStateError अपवाद फेंक दें।
  3. अगर अनुरोध विधि GET या HEAD , तो शरीर को शून्य पर सेट करें।
  4. यदि शरीर शून्य है, तो अगले चरण पर जाएं।

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

इसलिए, यदि आप किसी ब्राउज़र के XMLHttpRequest पर भरोसा करते हैं, तो संभवतः यह काम नहीं करेगा।


आईएमएचओ आप URL में सिर्फ JSON एन्कोडेड (यानी encodeURIComponent ) भेज सकते हैं, इस तरह आप HTTP चश्मा का उल्लंघन नहीं करते हैं और सर्वर पर अपना JSON प्राप्त नहीं करते हैं।


उदाहरण के लिए, यह कर्ल, अपाचे और PHP के साथ काम करता है।

PHP फ़ाइल:

<?php
echo $_SERVER['REQUEST_METHOD'] . PHP_EOL;
echo file_get_contents('php://input') . PHP_EOL;

कंसोल कमांड:

$ curl -X GET -H "Content-Type: application/json" -d '{"the": "body"}' 'http://localhost/test/get.php'

आउटपुट:

GET
{"the": "body"}

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

रोबस्टनेस सिद्धांत के पीछे यह भावना लगभग "जो आप स्वीकार करते हैं उसमें उदार हो, और जो भी आप भेजते हैं उसमें रूढ़िवादी हो", आप बिना किसी कारण के विनिर्देश की सीमाओं को धक्का देना चाहते हैं।

हालांकि, अगर आपके पास कोई अच्छा कारण है, तो इसके लिए जाएं।


न तो रेस्टिएंट और न ही रीस्ट कंसोल इसका समर्थन करता है लेकिन कर्ल करता है।

HTTP विनिर्देश खंड 4.3 में कहता है

अनुरोध विधि (धारा 5.1.1) का विनिर्देश अनुरोध में इकाई-निकाय भेजने की अनुमति नहीं देता है, तो एक संदेश-निकाय को अनुरोध में शामिल नहीं किया जाना चाहिए।

धारा 5.1.1 विभिन्न विधियों के लिए हमें अनुभाग 9 .x पर रीडायरेक्ट करता है। उनमें से कोई भी संदेश निकाय को शामिल करने पर स्पष्ट रूप से प्रतिबंधित नहीं है। तथापि...

धारा 5.2 कहता है

इंटरनेट अनुरोध द्वारा पहचाना जाने वाला सटीक संसाधन अनुरोध-यूआरआई और होस्ट हेडर फ़ील्ड दोनों की जांच करके निर्धारित किया जाता है।

और धारा 9.3 कहता है

जीईटी विधि का अर्थ है अनुरोध-यूआरआई द्वारा जो भी जानकारी (किसी इकाई के रूप में) को पुनर्प्राप्त किया जाता है।

जो एक साथ सुझाव देते हैं कि एक जीईटी अनुरोध संसाधित करते समय, किसी सर्वर को अनुरोध-यूआरआई और होस्ट हेडर फ़ील्ड की जांच करने की आवश्यकता नहीं होती है।

संक्षेप में, HTTP spec आपको GET के साथ एक संदेश-निकाय भेजने से नहीं रोकता है लेकिन पर्याप्त अस्पष्टता है कि यह मुझे आश्चर्य नहीं करेगा अगर यह सभी सर्वरों द्वारा समर्थित नहीं था।


मुझे परेशान है कि आरईएसटी प्रोटोकॉल के रूप में ओओपी का समर्थन नहीं करता है और विधि सबूत है। एक समाधान के रूप में, आप अपने डीटीओ को JSON पर क्रमबद्ध कर सकते हैं और फिर क्वेरी स्ट्रिंग बना सकते हैं। सर्वर पक्ष पर आप क्वेरी स्ट्रिंग को डीटीओ को deserialize करने में सक्षम हो जाएगा।

इस पर एक नज़र डालें

संदेश आधारित दृष्टिकोण आपको विधि प्रतिबंध प्राप्त करने में मदद कर सकता है। आप अनुरोध निकाय के साथ किसी भी डीटीओ को भेजने में सक्षम होंगे

नीलिबुर वेब सेवा ढांचा कार्यक्षमता प्रदान करता है जिसका आप उपयोग कर सकते हैं

var client = new JsonServiceClient(Settings.Default.ServiceAddress);
var request = new GetClientRequest
    {
        Id = new Guid("2217239b0e-b35b-4d32-95c7-5db43e2bd573")
    };
var response = client.Get<GetClientRequest, ClientResponse>(request);

as you can see, the GetClientRequest was encoded to the following query string

http://localhost/clients/GetWithResponse?type=GetClientRequest&data=%7B%22Id%22:%2217239b0e-b35b-4d32-95c7-5db43e2bd573%22%7D

मैंने यह प्रश्न आईईटीएफ HTTP डब्लूजीजी को दिया है। रॉय फील्डिंग (1 99 8 में http / 1.1 दस्तावेज़ के लेखक) की टिप्पणी थी

"... एक कार्यान्वयन को पार्स के अलावा कुछ भी करने के लिए तोड़ा जाएगा और प्राप्त होने पर उस निकाय को त्याग दिया जाएगा"

आरएफसी 7213 (HTTPbis) राज्यों

"एक जीईटी अनुरोध संदेश के भीतर एक पेलोड में कोई परिभाषित अर्थशास्त्र नहीं है;"

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

वहाँ प्रॉक्सी हैं जो आपके अनुरोध को निश्चित रूप से विभिन्न तरीकों से तोड़ देंगे यदि आप जीईटी पर एक बॉडी शामिल करते हैं।

तो संक्षेप में, ऐसा मत करो।


यदि आप कभी भी कैशिंग का लाभ उठाने का प्रयास करते हैं तो आपको शायद समस्याएं आती हैं। प्रॉक्सी प्रतिक्रिया प्राप्त करने पर प्रभाव डालने के लिए जीईटी बॉडी में नहीं जा रहे हैं।


आरएफसी 2616, सेक्शन 4.3 , "संदेश बॉडी" से:

एक सर्वर को किसी भी अनुरोध पर संदेश-शरीर को पढ़ना और अग्रेषित करना चाहिए; अगर अनुरोध विधि में इकाई-निकाय के लिए परिभाषित अर्थशास्त्र शामिल नहीं है, तो अनुरोध को संभालने के दौरान संदेश-निकाय को अनदेखा किया जाना चाहिए।

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

यह ऊपर फ़ील्डिंग से उद्धरण के अनुरूप है।

धारा 9.3 , "जीईटी", जीईटी विधि के अर्थशास्त्र का वर्णन करता है, और अनुरोध निकायों का उल्लेख नहीं करता है। इसलिए, किसी सर्वर को किसी अनुरोध अनुरोध पर प्राप्त होने वाले किसी भी अनुरोध निकाय को अनदेखा करना चाहिए।


एक जीईटी अनुरोध के साथ एक शरीर सहित रॉय फील्डिंग की टिप्पणी

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

तो, हाँ, आप एक शरीर को जीईटी के साथ भेज सकते हैं, और नहीं, ऐसा करने में कभी भी उपयोगी नहीं होता है।

यह HTTP / 1.1 के स्तरित डिज़ाइन का हिस्सा है जो spec विभाजन के बाद फिर से स्पष्ट हो जाएगा (प्रगति पर काम)।

.... रॉय

हां, आप जीईटी के साथ एक अनुरोध निकाय भेज सकते हैं लेकिन इसका कोई अर्थ नहीं होना चाहिए। यदि आप इसे सर्वर पर पार्स करके और अपनी सामग्री के आधार पर अपनी प्रतिक्रिया बदलकर इसका अर्थ देते हैं , तो आप HTTP / 1.1 spec, section 4.3 में इस अनुशंसा को अनदेखा कर रहे हैं:

[...] यदि अनुरोध विधि में इकाई-निकाय के लिए परिभाषित अर्थशास्त्र शामिल नहीं है, तो अनुरोध को संभालने के दौरान संदेश-निकाय को अनदेखा किया SHOULD

और HTTP / 1.1 spec में GET विधि का विवरण , खंड 9.3 :

जीईटी विधि का मतलब है कि जो भी जानकारी पुनर्प्राप्त करें ([...]) अनुरोध-यूआरआई द्वारा पहचाना जाता है।

जिसमें कहा गया है कि अनुरोध-निकाय जीईटी अनुरोध में संसाधन की पहचान का हिस्सा नहीं है, केवल यूआरआई अनुरोध है।





http-get