1 पॉइंट द्वारा GN⁺ 4 시간 전 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • RFC 10008 एक HTTP QUERY मेथड को परिभाषित करता है, जिसमें अनुरोध बॉडी में दी गई क्वेरी को लक्षित resource safe और idempotent तरीके से प्रोसेस करता है और फिर परिणाम लौटाता है
  • QUERY, GET की safe/idempotent प्रकृति और POST की बॉडी-आधारित इनपुट शैली को जोड़ता है, जिससे लंबी URI, URI encoding की लागत, log exposure, और हर क्वेरी संयोजन को अलग resource मानने का बोझ कम होता है
  • सर्वर तभी QUERY अनुरोध को प्रोसेस कर सकता है जब उसका Content-Type और बॉडी एक-दूसरे के अनुरूप हों; unsupported type, बॉडी mismatch, और प्रोसेस न हो सकने वाली query को अलग-अलग 4xx responses से अलग किया जा सकता है
  • सफल response, Content-Location के जरिए query result resource और Location के जरिए उसी query को दोबारा चलाने वाले equivalent resource की जानकारी दे सकता है
  • QUERY responses cache किए जा सकते हैं, लेकिन cache key में बॉडी और metadata दोनों शामिल होने चाहिए; और CORS वातावरण में यह safelisted method नहीं है, इसलिए preflight आवश्यक है

QUERY जिस HTTP query pattern को हल करना चाहता है

  • RFC 10008 एक Internet Standards Track document है जो HTTP QUERY request method को परिभाषित करता है
  • QUERY अनुरोध करता है कि target resource अनुरोध बॉडी को प्रोसेस करे और उसका परिणाम response में लौटाए
  • यह POST की तरह बॉडी का उपयोग करता है, लेकिन safe और idempotent के रूप में परिभाषित है, इसलिए automatic retry या restart संभव है
  • मौजूदा GET queries में इनपुट को URI में रखना सामान्य है
    • GET /feed?q=foo&limit=10&sort=-published HTTP/1.1
  • जब query data को URI में रखा जाता है, तो डेटा बढ़ने के साथ सीमाएँ भी बढ़ती हैं
    • कई स्वतंत्र systems से होकर गुजरने के कारण वास्तविक URI size limit पहले से जानना कठिन होता है
    • HTTP भेजने वाले और पाने वाले से कम-से-कम 8000 octets support करने की सिफारिश करता है, लेकिन path में मौजूद हर system के लिए इसकी गारंटी नहीं देता
    • कुछ data को वैध URI के रूप में encode करने की लागत अधिक होती है
    • request URI, request body की तुलना में logs में रहने या bookmark में शामिल होने की अधिक संभावना रखता है
    • query को सीधे URI में encode करने पर हर संभावित input combination को अलग resource माना जाता है

GET और POST के बीच semantics को स्पष्ट करने वाला मेथड

  • कई implementations, GET की जगह POST बॉडी से query भेजती हैं
    • POST /feed
    • Content-Type: application/x-www-form-urlencoded
    • बॉडी: q=foo&limit=10&sort=-published
  • इस तरीके में, किसी विशेष resource और server knowledge के बिना यह स्पष्ट नहीं होता कि query safe और idempotent है या नहीं
  • QUERY वही input request body में भेजता है, लेकिन method स्वयं safe और idempotent होता है
    • QUERY /feed
    • Content-Type: application/x-www-form-urlencoded
    • बॉडी: q=foo&limit=10&sort=-published
  • इस स्पष्ट semantics की वजह से caching और automatic retry जैसी HTTP features लागू करना आसान हो जाता है
  • सर्वर query स्वयं या किसी specific query result के लिए URI दे सकता है, जिसे बाद में GET requests में उपयोग किया जा सकता है

QUERY मेथड के मुख्य नियम

  • QUERY का उपयोग server-side query शुरू करने के लिए किया जाता है
  • GET, target URI द्वारा पहचाने गए resource की representation मांगता है, जबकि QUERY, target resource के दायरे में query operation चलाने का अनुरोध करता है
  • request body और media type query को परिभाषित करते हैं, और origin server target resource के आधार पर operation का scope तय करता है
  • यदि Content-Type request field मौजूद नहीं है या request body से मेल नहीं खाता, तो सर्वर को अनुरोध विफल करना चाहिए
  • target URI का query part, बाकी सभी HTTP methods की तरह, query target resource की पहचान में भाग लेता है
    • वह query part परिणाम को सीधे प्रभावित करता है या नहीं, और कैसे करता है, यह resource-specific behavior है और इस specification के दायरे से बाहर है
  • target resource के दृष्टिकोण से QUERY safe है
    • client, target resource की state change का अनुरोध या अपेक्षा नहीं करता
    • सर्वर के लिए ऐसे HTTP resources बनाना मना नहीं है जिन्हें अतिरिक्त जानकारी देखने के लिए उपयोग किया जा सके
  • QUERY idempotent है, इसलिए connection failure के बाद जरूरत पड़ने पर इसे retry या repeat किया जा सकता है
  • 200 OK response यह दिखाता है कि query सफलतापूर्वक प्रोसेस हुई और उसका परिणाम response body में शामिल है

Media type, negotiation, error handling

  • QUERY request का अर्थ request body और media type जैसे संबंधित metadata पर निर्भर करता है
  • जिन requests में body और metadata एक-दूसरे से मेल नहीं खाते, उन्हें सामान्यतः 4xx Client Error के साथ reject किया जाना चाहिए
  • error handling इस बात पर निर्भर करती है कि request में समस्या कहाँ है
    • यदि media type की जानकारी नहीं है, तो request परिभाषा के स्तर पर गलत है, इसलिए इसे 400 जैसे 4xx status code से fail होना चाहिए
    • यदि media type दिया गया है लेकिन resource उसे support नहीं करता, तो 415 Unsupported Media Type उपयुक्त है
    • यदि media type सिद्धांततः ज्ञात है, लेकिन target resource के लिए उसका QUERY semantics नहीं है, तो भी 415 उपयुक्त हो सकता है
    • यदि media type वास्तविक request body से मेल नहीं खाता, तो 400 Bad Request लौटाया जा सकता है
    • सर्वर, body देखकर media type का अनुमान लगाकर missing या गलत value को override करने वाली content sniffing नहीं कर सकता
    • यदि type और body मेल खाते हों, लेकिन वास्तविक query content के कारण उसे प्रोसेस नहीं किया जा सकता, तो 422 Unprocessable Content उपयोग किया जा सकता है
    • syntactically valid SQL query का ऐसी table की ओर इशारा करना जो मौजूद ही नहीं है, 422 का एक उदाहरण है
    • यदि client ने Accept के जरिए जिस response media type का अनुरोध किया है उसे resource support नहीं करता, तो 406 Not Acceptable उपयुक्त है
  • Accept-Query response field client को supported query media types की जानकारी दे सकता है

equivalent resource, Content-Location, Location

  • equivalent resource वह resource है जो किसी खास QUERY request और उसके target को दर्शाता है और GET requests का response दे सकता है
  • equivalent resource request body और metadata दोनों को ध्यान में रखता है
    • इसमें body का media type जैसी representation metadata शामिल होती है
  • सर्वर equivalent resource को URI दे सकता है, लेकिन यह अनिवार्य नहीं है
  • successful response, Content-Location header में उस resource identifier को शामिल कर सकता है जो query result से संबंधित है
    • client दिए गए URI पर GET भेजकर अभी-अभी की गई query operation का परिणाम प्राप्त कर सकता है
    • वह resource अस्थायी हो सकता है
  • successful response, Location header में QUERY request के equivalent resource का URI शामिल कर सकता है
    • client, query body दोबारा भेजे बिना दिए गए URI पर GET भेजकर वही query operation फिर से कर सकता है
    • यह URI भी अस्थायी हो सकता है
    • यदि बाद का request विफल हो जाए, तो client मूल QUERY target और पहले सबमिट की गई body के साथ फिर कोशिश कर सकता है

Redirection और conditional requests

  • सर्वर QUERY request के लिए user agent को किसी दूसरे URI पर redirect करने वाला indirect response चुन सकता है
  • 301 Moved Permanently और 308 Permanent Redirect यह दर्शाते हैं कि target resource स्थायी रूप से Location द्वारा बताए गए दूसरे URI पर चला गया है
  • 302 Found और 307 Temporary Redirect, target resource के अस्थायी relocation को दर्शाते हैं
  • सभी चार स्थितियों में सर्वर यह सुझाव देता है कि नए target URI पर समान QUERY request भेजकर मूल request पूरा किया जा सकता है
  • 301 या 302 के बाद POST को GET में redirect करने वाला अपवाद, QUERY requests पर लागू नहीं होता
  • QUERY के लिए 303 See Other यह दर्शाता है कि मूल query को Location द्वारा बताए गए URI पर सामान्य retrieval request के रूप में किया जा सकता है
    • HTTP में इसका मतलब नए target URI पर GET request भेजना है
  • conditional QUERY में selected representation वही होती है जो उस QUERY request के equivalent resource पर किए गए GET में होती
  • client यह अनुरोध कर सकता है कि response में query result तभी लौटाया जाए जब conditional headers में दी गई शर्तें पूरी हों

Caching और Range requests

  • QUERY method responses cacheable हैं, और cache का उपयोग बाद की QUERY requests को संतुष्ट करने के लिए किया जा सकता है
  • QUERY request की cache key में request body और संबंधित metadata शामिल होना चाहिए
  • cache, cache key बनाने के लिए semantics के लिहाज़ से महत्वहीन अंतर हटा सकता है
    • content encoding हटाना
    • +json जैसे media subtype suffix द्वारा दर्शाई गई format conventions के अनुसार normalization
    • Content-Type द्वारा व्यक्त body semantics के अनुसार normalization
  • ये transformations केवल cache key generation के लिए होते हैं; वे actual request को नहीं बदलते
  • client, no-transform cache directive के जरिए यह संकेत दे सकता है कि वह ऐसे transformations नहीं चाहता, लेकिन यह directive advisory है
  • QUERY response caching, GET की तुलना में स्वाभाविक रूप से अधिक जटिल है
    • cache key तय करने के लिए पूरी request body पढ़नी पड़ती है
    • यदि QUERY response, Location के माध्यम से equivalent resource URI देता है, तो client बाद में GET पर switch करके processing सरल कर सकता है
  • QUERY के लिए Range Request का semantics, GET जैसा ही है
  • लिखे जाने के समय परिभाषित एकमात्र range unit, Byte Range Request, QUERY results के लिए बहुत कम उपयोगी है
  • अक्सर query format स्वयं ही result limiting या pagination देता है, जैसे SQL का FETCH FIRST ... ROWS ONLY; इसलिए ऐसी built-in features के उपयोग की अपेक्षा की जाती है

Accept-Query response header

  • Accept-Query response header सीधे यह बताता है कि resource QUERY method को support करता है और कौन-कौन से query format media types उपयोग किए जा सकते हैं
  • Accept-Query, Structured Fields syntax का उपयोग करने वाली media range की list है
  • media range को बिना parameters वाले media range value वाले Token या String की List Structured Header Field के रूप में व्यक्त किया जाता है
  • media type parameters को Structured Field Parameters में map किया जाता है
    • String और Token का चयन semantics के स्तर पर महत्वपूर्ण नहीं है
    • receiver, Token को String में बदल सकता है, लेकिन मिले हुए type के आधार पर अलग व्यवहार नहीं करना चाहिए
  • media type, Token से पूरी तरह exact mapping नहीं रखता, और जहाँ leading digits की अनुमति हो वहाँ String form का उपयोग करना चाहिए
  • supported wildcard केवल */* या xxxx/* हैं
  • field value में सूचीबद्ध types का क्रम महत्वपूर्ण नहीं है
  • Accept-Query value, same path साझा करने वाले server के सभी URI पर लागू होती है, और query component को नज़रअंदाज़ किया जाता है
  • यदि उसी resource के requests अलग-अलग Accept-Query values लौटाएँ, तो सबसे हाल में प्राप्त fresh value का उपयोग किया जाता है
  • उदाहरण इस प्रकार है
    • Accept-Query: "application/jsonpath", application/sql;charset="UTF-8"
  • Accept-Query, Accept जैसा दिख सकता है, लेकिन यह Structured Field है, इसलिए इसे RFC 9651 के Structured Fields processing rules के अनुसार संभालना चाहिए

Security considerations और CORS

  • QUERY, RFC 9110 में परिभाषित सभी HTTP methods के सामान्य security considerations का पालन करता है
  • QUERY, request information को URI query component में रखने वाले तरीके का एक विकल्प हो सकता है
  • URI, request body की तुलना में logs में आने या intermediaries द्वारा प्रोसेस किए जाने की अधिक संभावना रखते हैं, इसलिए संवेदनशील जानकारी वाली queries के लिए QUERY, GET की तुलना में अधिक उपयुक्त हो सकता है
  • जब सर्वर QUERY result को दर्शाने वाला अस्थायी resource बनाता है और उसे URI देता है, तब यदि मूल request body में ऐसी संवेदनशील जानकारी हो जिसे logs में नहीं जाना चाहिए, तो उस URI में वह संवेदनशील हिस्सा शामिल नहीं होना चाहिए
  • यदि cache, QUERY body को गलत normalize करे, या resource processing के तरीके से बहुत अलग normalize करे, तो false positive के कारण गलत response लौट सकता है
  • CORS लागू करने वाले user agents की QUERY requests में preflight request आवश्यक है
    • QUERY, CORS-safelisted methods के सेट में शामिल नहीं है

IANA registration और method name selection

  • IANA, QUERY method को HTTP Method Registry में जोड़ता है
    • Method Name: QUERY
    • Safe: yes
    • Idempotent: yes
    • Specification: RFC 10008 Section 2
  • IANA, Accept-Query field को HTTP Field Name Registry में जोड़ता है
    • Field Name: Accept-Query
    • Status: permanent
    • Structured Type: List
  • HTTP Method Registry में पहले से ही safe और idempotent गुणों वाले PROPFIND, REPORT, SEARCH मौजूद थे
  • शुरुआती चरण में SEARCH का उपयोग किया गया था, लेकिन अंतिम method name QUERY बना
  • QUERY चुने जाने के कारण ये थे
    • alternatives, request body में सामान्य media type application/xml का उपयोग करते थे और request semantics पूरी तरह body पर निर्भर होते थे
    • ये सभी alternatives, WebDAV गतिविधियों से निकले थे
    • QUERY, URI के query component के साथ उसके संबंध को अच्छी तरह पकड़ता है

1 टिप्पणियां

 
GN⁺ 4 시간 전
Hacker News की राय
  • अगर मज़बूत प्रेरक उदाहरण होते तो बात ज़्यादा प्रभावशाली लगती, लेकिन ऐसे उदाहरण दिए गए हैं जिन्हें बहुत आसानी से GET से व्यक्त किया जा सकता है, इसलिए बात उल्टा बिखरी हुई लगती है
    अगर हम बड़े JSON फ़िल्टर स्ट्रक्चर या इमेज इनपुट को request body में डालने वाले QUERY की कल्पना भी करें, तब भी यह बहुत अजीब लगता है कि request body cache key का हिस्सा बन जाए। इससे user-controlled अनंत cache keys बन सकती हैं, और सामान्य caching strategies में व्यवहारिक रूप से request body की bit-level तुलना या hash करना ही बचेगा, जिससे दुर्भावनापूर्ण स्थिति में cache invalidation बहुत आसान हो जाता है
    अगर कोई ऐसी सेवा बना रहा है जिसे complex filtering या image जैसी जटिल input की ज़रूरत है, तो caching की परत शायद HTTP लेयर से काफ़ी दूर होगी। उदाहरण के लिए join के अलग-अलग data columns, या decoded image input के perceptual hash पर key की गई embeddings जैसी चीज़ें, जो wire पर मौजूद exact bit representation से स्वतंत्र होंगी
    समझ नहीं आता कि ऐसी चीज़ को ज़बरदस्ती सामान्य प्रयोजन के तरीके में क्यों पकड़ना है। इसके बजाय POST पर "Vary: request-body" जैसे नए header से caching semantics व्यक्त करना कहीं बेहतर लगता है। यह पूरी तरह backward compatible होगा, और 0.1% CDN use cases के अलावा, जहाँ यह व्यवहार उपयोगी हो सकता है, बाक़ी जगह इसे नज़रअंदाज़ भी किया जा सकेगा

    • GET के URI में मौजूद query part भी व्यवहार में लगभग बिना सीमा का, user-controlled होता है, और URI का हिस्सा होने के कारण cache key में भी जाता है। इसलिए इसका उल्टा मामला अलग से क्यों उठाया जा रहा है, यह साफ़ नहीं है
    • अगर browser को छोटी cache key चाहिए, तो body का collision-resistant hash store किया जा सकता है। उदाहरण के लिए SHA-256 इस्तेमाल किया जा सकता है
      caching पर होने वाले हमलों में ऐसा कुछ याद नहीं आता जो query parameters पर उसी तरह लागू न होता हो। अगर किसी को cache भर देना हो, तो unique 30-character query parameter बनाना 30MB request body बनाने जितना ही आसान है
    • हर use case public internet नहीं होता, और public internet पर उपयोगी न होना इसका मतलब यह भी नहीं कि उसे standardize नहीं किया जा सकता
      व्यवहार में public internet के लिए सिस्टम cache key के रूप में security hash का उपयोग करेंगे ताकि उसका आकार हमेशा एक जैसा रहे। cache key में पहले से ही बहुत लंबे URL और arbitrary header values के सेट शामिल हो सकते हैं
    • इमेज को request body में भेजा जा सकता है, लेकिन यह पहले से base64 query parameter के रूप में भी किया जा सकता है। अगर कोई अजीब तरीक़े से इस्तेमाल करना चाहे, तो किसी भी proposed standard का बुरा इस्तेमाल किया जा सकता है
      query parameters वाले GET पहले से ही opaque हैं और cache invalidation को आसान बनाते हैं
    • उदाहरण के लिए मैं अभी database के लिए एक MCP server बना रहा हूँ। ChatGPT में commit से पहले rollback होने वाला dry-run POST करना चाहता हूँ, लेकिन दोनों बस एक property से अलग POST requests हैं, इसलिए tool की safety layer बार-बार सक्रिय हो जाती है। कई कारणों से इसका सही कारण debug करना भी मुश्किल है
      लेकिन अगर POST से पहले QUERY हो, तो शायद यह बेहतर होगा। क्योंकि तब यह केवल safety flag लगे हुए वही request नहीं रहेगा, बल्कि अलग request type होगा
  • सोच रहा हूँ कि क्या HTML forms में QUERY support जोड़ा जाएगा
    QUERY idempotent होना चाहिए, इसलिए POST form submission के result page को refresh करने पर आने वाली परेशान करने वाली resubmission warning से बचा जा सकता है

    • HTML forms में GET/POST के अलावा और methods का support मिलना दशकों से चाहा गया है। संयोग से एक WHATWG proposal मौजूद है, तो अगर आप समर्थन देना चाहते हैं, यहाँ जाएँ: https://github.com/whatwg/html/pull/11347
    • forms की एक अजीब बात यह है कि form POST का result एक ऐसे page के रूप में आता है जिसका location(URL) होता है, लेकिन उसे उसी location से load नहीं किया जा सकता। जहाँ तक मुझे पता है, यह तथ्य कि वह page GET नहीं बल्कि POST था, user या JS को दिखने वाली किसी जगह पर store नहीं होता, और refresh भी अजीब तरह से व्यवहार करता है
      अगर method=QUERY जुड़ता है, तो इस अजीबपन का एक नया रूप और बढ़ जाएगा
    • इसे POST-Redirect-GET pattern से हल करना बेहतर है
    • https://github.com/whatwg/html/issues/12594 देखें
    • उन्होंने अब तक कभी अन्य verbs का support नहीं जोड़ा, लेकिन अब नया दौर है, तो पता नहीं क्या हो
  • जो लोग अब भी पिछली सदी का एहसास लेना चाहते हैं, उनके लिए: https://www.rfc-editor.org/rfc/rfc10008.txt

    • ऐसे लंबे और पूरी तरह plain text documents मुझे शायद हमेशा पसंद आएँगे। बचपन में वीडियो गेम FAQ पढ़ने के अच्छे दिन याद आ जाते हैं। कई मायनों में यह सचमुच एक बेहतर information format है
    • इसकी formatting बहुत सुंदर है। इसे internal work memo के style template के रूप में कॉपी करना चाहिए। यह timeless है
  • “GET request के साथ body जोड़ने का विकल्प IETF working group में गहराई से विचार किया गया था, लेकिन अंततः नया QUERY method बनाने का फ़ैसला हुआ। अलग method बनाने का यह निर्णय historical interoperability issues और HTTP की core architectural definitions के सख़्त पालन के कारण लिया गया”
    लेकिन मैं तो कई सालों से GET method के साथ request body भेज रहा हूँ

    • कुछ load balancers body को discard कर देते हैं
    • आम तौर पर यह अच्छा विचार नहीं है। कुछ HTTP implementations में यह संभव ही नहीं है। उदाहरण के लिए fetch
      https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/U...
      “GET requests cannot include a body”
      transparent caching की वजह से अजीब समस्याएँ भी हो सकती हैं
  • यह देखकर हैरानी होती है कि अब हम 5-अंकों वाले RFC numbers तक पहुँच गए हैं

  • किसी ने RFC 10000 कब प्रकाशित होगा इस पर एक vague bet लगाई थी, लेकिन numbering 9998 से सीधे 10008 पर चली गई। कोई नहीं जीता
    https://manifold.markets/CollectedOverSpread/when-will-rfc-1...

  • अब स्थिति ऐसी लगती है कि अगर HTTP query में search result query करना हो, तो QUERY method इस्तेमाल करो और query parameters मत जोड़ो
    नाम थोड़ा उलझाने वाला है। query शब्द पहले से सामान्य रूप में HTTP requests के लिए इस्तेमाल होता है
    सिर्फ RFC का शीर्षक देखकर ही भ्रम हुआ

    • query शब्द HTTP requests के लिए सामान्य रूप में किस क्षेत्र में इस्तेमाल होता है? बोलचाल में GET request को query कह सकते हैं, लेकिन POST, PUT, DELETE को तो कभी नहीं कहते
    • सही। और यह ज़रूरी भी नहीं कि यह query ही हो; यह idempotent effect भी हो सकता है। शायद इसे IPOST, यानी idempotent POST कहना बेहतर होता
      संपादन: ओह, cacheability के लिए QUERY को side-effect-free “safe” method घोषित किया गया है। मेरी ग़लती थी
  • अगर यह सच में query string वाले GET requests को व्यवहारिक दुनिया में replace करने लगे, तो उम्मीद है कि browser bookmarks request parameter preservation का समर्थन करेंगे

    • शायद ऐसा नहीं होगा। ज़्यादा संभावना यह है कि यह उन जगहों को replace करेगा जहाँ अभी query purpose के लिए POST इस्तेमाल होता है
  • यह इस RFC के दायरे से बाहर है, लेकिन अच्छी बात यह है कि इसे आसानी से बढ़ाकर JS EventSource को streaming AI queries के लिए भी काम करने लायक बनाया जा सकता है
    request में body चाहिए होती है, इसलिए सब लोग POST का उपयोग करते हैं, और streaming result के लिए response में अक्सर text/event-stream protocol इस्तेमाल होता है। लेकिन वास्तव में state बदल नहीं रही होती, इसलिए तकनीकी रूप से यह ठीक मेल नहीं खाता, और EventSource ज़िद्दी तरीके से केवल GET ही इस्तेमाल कर सकता है। इसलिए बहुत-सी APIs वही functionality अपने parser के साथ दोबारा implement करती हैं

  • GET: Content (body) "no defined semantics" देखकर लगा था कि GET method में body की अनुमति देना इतना बुरा नहीं होगा, लेकिन मूल spec के अनुसार GET body को पूरी तरह नज़रअंदाज़ किया जाना चाहिए
    साथ ही अगर request का महत्वपूर्ण हिस्सा body में हो और उसे हटा दिया जाए, तो caching भी टूट सकती है

    • केवल URI वाला GET इस semantics के साथ आता है कि वह resource की current representation लाता है। यही hyperlink का सबसे बुनियादी रूप है और web के काम करने के तरीके के लिए काफ़ी महत्वपूर्ण है
      अगर GET में body parameters जोड़ दिए जाएँ, तो एक ही URI का उपयोग करने वाली दो requests को एक ही चीज़ की ओर इशारा करने वाला नहीं माना जा सकेगा, और इससे method की यह सीमा टूट जाती है