URL, पाथ और क्वेरी पैरामीटर
URL किसी resource का पता है, और उसके parameters उस पते में लिखे गए inputs हैं। https://shop.example.com/stores/riyadh-01/products?q=green%20tea&page=2 में path parameter riyadh-01 store चुनता है, और query parameters q और page search term और results का page तय करते हैं। %20 एक encoded space है, क्योंकि URL में सीधा space नहीं आ सकता।
HTTP methods वाले lesson में आपने देखा कि हर request एक method को एक target के साथ जोड़ती है। यह lesson उस target को खोलता है: RFC 3986 के अनुसार URL के हिस्से, path और query parameters, values को सही रखने वाली encoding, और हर parameter को टेस्ट करने का तरीका।
यह क्यों ज़रूरी है
Parameters ऐसे input fields हैं जिन्हें UI छिपा देता है। Search terms, IDs, filters और page numbers URL में चलते हैं, इसलिए उन्हें form field जैसा ही test design चाहिए। गलत handle हों तो "tea & coffee" का search गलत products लौटाता है, कोई filter चुपचाप ignore हो जाता है, या /orders/1001 को /orders/1002 करने पर किसी दूसरे customer का order दिख जाता है। यह Broken Object Level Authorization है, OWASP API Security Top 10 2023 का पहला risk।
URL edit करना किसी input को आज़माने या report reproduce करने का सबसे तेज़ तरीका भी है, और encoded रूप में exact URL वह सबसे सटीक evidence है जो किसी bug report में हो सकता है।
URL के पाँच हिस्से
RFC 3986 URI का generic syntax पाँच हिस्सों में परिभाषित करता है: scheme://authority/path?query#fragment। हर हिस्सा एक तय delimiter पर ख़त्म होता है, इसलिए आप किसी भी URL को हाथ से बाँट सकते हैं; browsers जिस WHATWG URL Standard को follow करते हैं, वह भी इसे इसी तरह बाँटता है।
Client scheme और authority से connection बनाता है, path और query को request target के रूप में भेजता है, और host को Host header में रखता है। Fragment कभी browser से बाहर नहीं जाता, इसलिए उसे न server log देखता है न कोई API test।
- Scheme:
httpsयाhttp; यही default port भी तय करता है, 443 या 80। - Authority: host, जैसे
shop.example.com, और optional:port। Scheme और host case-sensitive नहीं होते। - Path:
/stores/riyadh-01/products,/से अलग किए गए segments जो resource की पहचान करते हैं। - Query:
?के बाद से#तक सब कुछ। - Fragment:
#के बाद सब कुछ, जैसे#reviews: page के अंदर कोई जगह या single-page app के अंदर कोई route।
riyadh-01 store चुनता है, q और page list को refine करते हैं, और #reviews fragment server तक कभी नहीं पहुँचता।Address bar में URL
भाग 1:https://
Server को मिलने वाली request line
GET
Host header
Host:
- 3–6Request target: path और query
- 5–6Query:
&से जुड़ेkey=valuepairs
- 1SchemeDefault port तय करता है,
httpsके लिए 443, इसलिए:portनहीं लिखा गया - 2Authority (host)Connection के लिए इस्तेमाल होता है, फिर
Hostheader में जाता है; case-sensitive नहीं - 3Fixed path segmentsTemplate
/stores/{storeId}/productsमें हर store के लिए एक जैसे - 4Path parameter
storeIdStore चुनता है, इसलिए required है; unknown store को404मिलना चाहिएrequired - 5Query parameter
qSearch term, percent-encoded; server इसे decode करके यह पाता है:green tea - 6Query parameter
pageआम तौर पर optional और default के साथ, इसलिए इसे छोड़ना अपने-आप में एक test हैoptional - 7Fragmentसिर्फ़ browser इसे handle करता है, इसलिए request line में नहीं हैनहीं भेजा जाता
पाठ संस्करण
https://shop.example.com/stores/riyadh-01/products?q=green%20tea&page=2#reviews
scheme https
authority shop.example.com (no port: 443, the https default)
path /stores/riyadh-01/products
query q=green%20tea&page=2
fragment reviews (stays in the browser)
What the server receives:
GET /stores/riyadh-01/products?q=green%20tea&page=2 HTTP/1.1
Host: shop.example.comPath parameters: कौन-सा resource
RFC 3986 सिर्फ़ path segments जानता है। "Path parameter" API design में उस segment का नाम है जिसकी value हर request में बदलती है: documentation एक template लिखता है, /stores/{storeId}/products, और हर request उसे भरती है। OpenAPI ऐसे parameter को in: path से mark करता है; websites भी पढ़ने लायक slugs के लिए यही तरीका अपनाती हैं, जैसे /products/green-tea-500g।
Path parameter resource की पहचान करता है, इसलिए required होता है: /stores//products किसी दूसरे route पर पहुँचता है या कहीं नहीं। गलत type की value, जैसे numeric ID के लिए /orders/abc, को 4xx client error मिलना चाहिए, 500 नहीं; जो ID मौजूद नहीं उसे 404 मिलना चाहिए; और किसी दूसरे user की ID कभी उस user का data नहीं लौटानी चाहिए। Value के अंदर encoded slash %2F को अलग-अलग servers अलग तरह handle करते हैं, इसलिए intended behaviour पूछें और उसे टेस्ट करें।
Query parameters: resource को कैसे पढ़ें
Query request को refine करती है: search, filter, sort, pagination। RFC 3986 सिर्फ़ यह तय करता है कि query कहाँ शुरू और कहाँ ख़त्म होती है; & से जुड़े key=value pairs HTML form format application/x-www-form-urlencoded से आते हैं, जिसे WHATWG URL Standard परिभाषित करता है और ज़्यादातर frameworks follow करते हैं। Query parameters आम तौर पर optional होते हैं और उनके defaults होते हैं, इसलिए parameter का न होना भी एक behaviour है। इनमें से हर एक अलग input है:
?page=2: value वाली key।?page=या?page: key मौजूद है पर खाली है, जोpageको पूरी तरह छोड़ने जैसा नहीं है।?tag=tea&tag=gifts: दोहराई गई key। कोई standard नहीं बताता कि कौन-सी value मानी जाएगी; frameworks पहली, आख़िरी या सभी values लेते हैं।?Page=2: कई frameworks keys को case-sensitive मानते हैं, इसलिए यह एक unknown key हो सकती है जो चुपचाप ignore हो जाए।
Percent-encoding: values को सही-सलामत रखना
RFC 3986 उन characters को reserve करता है जो URL की बनावट तय करते हैं: : / ? # [ ] @ हिस्सों को अलग करते हैं, और ! $ & ' ( ) * + , ; = उनके अंदर के data को। A से Z और a से z तक के letters, 0 से 9 तक के digits और - . _ ~ को कभी encoding नहीं चाहिए। Value के अंदर कोई भी दूसरा character, space समेत, percent-encode किया जाना चाहिए: हर byte % और उसके बाद दो hexadecimal digits बन जाता है।
ASCII 128 characters का बुनियादी set है: Latin letters, digits, symbols और control codes। इसके बाहर के characters पहले UTF-8 से bytes में बदलते हैं, जो web का character encoding है: ASCII character एक byte लेता है और कोई भी दूसरा character दो से चार bytes। Arabic शब्द قهوة (coffee) में चार letters हैं और हर letter दो bytes का है, इसलिए वह आठ encoded bytes बनकर जाता है: %D9%82%D9%87%D9%88%D8%A9। हर value को अलग से encode करें, पूरे URL को कभी नहीं, वरना / और ? बदलकर %2F और %3F हो जाते हैं और URL टूट जाता है।
+का मतलब space सिर्फ़ form-encoded data में होता है, और ज़्यादातर servers query को ऐसे ही पढ़ते हैं; path में यह plus sign है। असली plus को%2Bलिखें, वरना+966…एक space और उसके बाद966…बनकर पहुँचता है।- एक बार encode, एक बार decode।
%2520दो बार encode किया गया space है, और जो server दो बार decode करता है वह किसी encoded character को input validation से बच निकलने दे सकता है।
Value Encoded query value
green tea green%20tea
tea & coffee tea%20%26%20coffee
50% 50%25
#1 seller %231%20seller
+966500000000 %2B966500000000
قهوة %D9%82%D9%87%D9%88%D8%A9Worked example: product list URL की टेस्टिंग
Requirement: GET /api/v1/stores/{storeId}/products किसी store के products दिखाता है। q optional search term है; sort की value price_asc (default) या price_desc है; page 1 से शुरू होने वाला integer है, default 1; limit 1 से 50 तक का integer है, default 20। Unknown store को 404 मिलता है; किसी parameter की invalid value को 400 और उस parameter का नाम लेने वाला message मिलता है।
यहाँ ज़्यादातर काम दो test design techniques करती हैं, और दोनों का अपना lesson है जो उन्हें विस्तार से सिखाता है: equivalence partitioning किसी parameter की values को partitions में बाँटती है, यानी ऐसे groups जिनके साथ system को एक जैसा व्यवहार करना चाहिए, जैसे limit की valid और invalid values, और हर partition से एक value टेस्ट करती है; फिर boundary value analysis हर partition के किनारे वाली value और उस किनारे के पार की सबसे नज़दीकी value टेस्ट करती है, जैसे limit=50 और limit=51। दोनों को हर parameter पर लगाएँ, फिर URL वाले cases जोड़ें: missing, empty, repeated, unknown और encoded values। नीचे की requests के expected results:
- कोई query नहीं:
200, page 1, अधिकतम 20 products, सबसे सस्ता पहले। - Unknown store
riyadh-99:404, न खाली list और न500। limit=50स्वीकार होता है;limit=51को400औरlimitका नाम लेने वाला message मिलता है। निचली boundary के लिएlimit=1औरlimit=0जोड़ें।page=0,page=abcऔरsort=newest:400, न500और न कोई ऐसा fallback जो documentation में नहीं लिखा।- दोनों searches decode होकर "tea & coffee" और قهوة बननी चाहिए और matching products लौटाने चाहिए। फिर UI से search दोहराएँ और DevTools के Network tab में request जाँचें: strings जोड़कर URL बनाने वाला page
q=tea%20&%20coffeeभेजता है, और serverqको "tea " पढ़ता है, साथ में एक भटकी हुई key। - दोहराया गया
pageऔर unknowndebug: expected result documentation से आना चाहिए; कुछ लिखा न हो तो पूछें।
GET /api/v1/stores/riyadh-01/products
GET /api/v1/stores/riyadh-99/products
GET /api/v1/stores/riyadh-01/products?limit=50
GET /api/v1/stores/riyadh-01/products?limit=51
GET /api/v1/stores/riyadh-01/products?page=0
GET /api/v1/stores/riyadh-01/products?page=abc
GET /api/v1/stores/riyadh-01/products?sort=newest
GET /api/v1/stores/riyadh-01/products?q=tea%20%26%20coffee
GET /api/v1/stores/riyadh-01/products?q=%D9%82%D9%87%D9%88%D8%A9
GET /api/v1/stores/riyadh-01/products?page=2&page=3
GET /api/v1/stores/riyadh-01/products?debug=trueआज़माएँ: API क्वेरी पैरामीटर बिल्डर आज़माएँ: स्पेशल कैरेक्टर डेटासेट जनरेटर
आम गलतियाँ
- Strings जोड़कर URLs बनाना, जिससे
&,#,+या%वाली value request तोड़ देती है या उसका मतलब बदल देती है। - हर value की जगह पूरे URL को encode करना, या किसी value को दो बार encode करना।
- सिर्फ़ valid values टेस्ट करना; missing, empty, गलत type, boundary, repeated या unknown values कभी नहीं।
- यह उम्मीद करना कि server fragment देखेगा:
#के बाद का सब कुछ browser में ही रहता है। - Query string में tokens, passwords या personal data स्वीकार करना। URLs server logs, proxy logs और browser history में रहते हैं, और RFC 9110 उनमें sensitive information रखने के ख़िलाफ़ चेतावनी देता है।
- Path parameter पर इसलिए भरोसा करना कि UI दूसरों की IDs नहीं दिखाता, बजाय यह जाँचने के कि server दूसरे user का resource देने से मना करता है।
QA का नज़रिया
जब कोई requirement या API reference नया parameter लाए, तो पूछें: क्या यह required है, default क्या है, कौन-सी values और limits allowed हैं, क्या यह case-sensitive है, और missing, empty, repeated या unknown होने पर क्या होता है? हर जवाब एक expected result बनता है, और हर "किसी को नहीं पता" coding शुरू होने से पहले का एक सवाल।
Test cases और bug reports में पूरा URL ठीक वैसा ही लिखें जैसा भेजा गया था, दोबारा टाइप करने की जगह Network tab या API client से copy करके, और साथ में हर ज़रूरी parameter की decoded value भी। किसी दूसरे user के data तक पहुँचने के लिए path parameter बदलना सिर्फ़ authorised testing में होता है: अपने test accounts इस्तेमाल करें, ऐसे environment में जिसे टेस्ट करने की आपको अनुमति है, और कोई leak मिले तो उसे team की security process से report करें।
अभ्यास
Order list URL पढ़ें और टेस्ट करें
एक store manager कहता है कि order list गलत लग रही है और नीचे वाला URL भेजता है। उसके ऊपर endpoint का reference है: यह एक store के orders उसी store के signed-in manager को लौटाता है।
पहले काग़ज़ पर हल करें, फिर अपना बँटवारा URL पार्सर से और अपनी encoding URL एन्कोडर से जाँचें।
GET /stores/{storeId}/orders
storeId path required example: riyadh-01
status query optional new | paid | shipped default: all
customer query optional free text
page query optional integer >= 1 default: 1
errors 400 for an invalid parameter value, 404 for an unknown storeId
https://admin.example.com/stores/riyadh-01/orders?status=paid&page=0#list- URL को उसके पाँच हिस्सों में बाँटें। कौन-सा हिस्सा server तक कभी नहीं पहुँचता?
- Path और query parameters के नाम लिखें और हर value को reference से मिलाएँ।
- "Al Noor & Sons" customer के लिए
customerfilter encode करें। - Expected results के साथ आठ tests लिखें।
मॉडल उत्तर दिखाएँ
Scheme https; authority admin.example.com (default port 443); path /stores/riyadh-01/orders; query status=paid&page=0; fragment list, जो browser में ही रहता है।
Path parameter storeId = riyadh-01; query parameters status = paid और page = 0। page=0 minimum 1 से कम है, इसलिए expected result 400 है। अगर फिर भी list load हुई, तो शायद यही reported defect है।
customer=Al%20Noor%20%26%20Sons (form encoding Al+Noor+%26+Sons भी स्वीकार करती है)। Encode किए बिना & value को ख़त्म कर देता है, और server customer को "Al Noor " पढ़ता है, साथ में एक भटकी हुई key " Sons"।
Tests: (1) कोई query नहीं: सभी statuses, page 1। (2) हर allowed status: सिर्फ़ matching orders। (3) status=cancelled: 400। (4) page=-1 और page=abc: 400। (5) page=1 और आख़िरी page orders लौटाते हैं। (6) &, %, + और Arabic letters वाला encoded customer: पूरे नाम पर match। (7) Unknown store riyadh-99: 404। (8) आपके किसी दूसरे test account का store: 403 या 404, और कोई order data नहीं। Repeated status पर क्या होना चाहिए, यह पूछें।
अक्सर पूछे जाने वाले सवाल
URL और URI में क्या अंतर है?
URI किसी resource की पहचान करता है। RFC 3986 किसी URI को URL तब कहता है जब वह यह भी बताए कि resource तक कैसे पहुँचना है, जैसे https scheme और host से। दोनों का generic syntax एक ही है, और web testing में दोनों शब्द लगभग एक ही अर्थ में इस्तेमाल होते हैं।
URL में + space है या plus sign?
यह उसकी जगह पर निर्भर है। Form data (application/x-www-form-urlencoded) के रूप में पढ़ी जाने वाली query में + space है; path में यह plus sign है। असली plus को %2B और space को %20 लिखें, तो value का अर्थ हर जगह एक ही रहेगा।
क्या URLs case-sensitive होते हैं?
Scheme और host नहीं: HTTPS://Shop.Example.com और https://shop.example.com एक ही हैं। RFC 3986 बाकी हिस्सों को case-sensitive मानता है, पर हर server ख़ुद तय करता है कि उन्हें कैसे match करे, इसलिए /Products चल सकता है, redirect हो सकता है या 404 दे सकता है। इसे टेस्ट करें और team ने जो behaviour चुना है उसे दर्ज करें।
URL कितना लंबा हो सकता है?
कोई standard एक maximum तय नहीं करता। RFC 9110 recommend करता है कि senders और recipients कम से कम 8000 octets के URIs support करें, और browsers, servers और proxies अपनी-अपनी limits लगाते हैं। लंबाई की वजह से URL ठुकराने वाले server को 414 URI Too Long लौटाना चाहिए। अपने system की limit पूछें और उसके ठीक नीचे और ठीक ऊपर टेस्ट करें।
संदर्भ
- RFC 3986: Uniform Resource Identifier (URI): Generic SyntaxURI के भाग (स्कीम, अथॉरिटी, पाथ, क्वेरी, फ़्रैगमेंट), रिज़र्व्ड कैरेक्टर और परसेंट-एन्कोडिंग।
- URL Standardब्राउज़र वास्तव में URL को कैसे पार्स, सीरियलाइज़ और एन्कोड करते हैं, application/x-www-form-urlencoded सहित।
- RFC 9110: HTTP SemanticsHTTP मेथड, हेडर फ़ील्ड, स्टेटस कोड और कंटेंट निगोशिएशन के अर्थ, वायर वर्ज़न से स्वतंत्र।
- OWASP API Security Top 10 (2023)API की दस सबसे आम कमज़ोरियाँ: ऑब्जेक्ट-लेवल ऑथराइज़ेशन का टूटना, ऑथेंटिकेशन का टूटना, अनियंत्रित रिसोर्स खपत और अन्य।
Mutqan tools से अभ्यास करें
किसी URL को protocol, host, port, path, क्वेरी पैरामीटर, fragment और क्रेडेंशियल में तोड़ें।
क्वेरी स्ट्रिंग पार्स करें और बनाएँ — दोहराई गई key और bracket-array नोटेशन सहित।
URL, क्वेरी स्ट्रिंग और फ़ॉर्म डेटा में सुरक्षित इस्तेमाल के लिए टेक्स्ट को percent-encode करें।
Percent-encoded URL और क्वेरी स्ट्रिंग को वापस पढ़ने योग्य टेक्स्ट में डिकोड करें।
API कॉल के लिए pagination, filtering और sorting पैरामीटर के साथ सही एन्कोड की गई क्वेरी स्ट्रिंग बनाएँ।
स्पेशल कैरेक्टर से भरे इनपुट जनरेट करें: कोट, SQL/HTML/JSON मेटाकैरेक्टर, कंट्रोल कैरेक्टर, emoji और path की चालाकियाँ।
और गहराई से
इस topic में आपकी प्रगति
प्रगति ट्रैक करने के लिए साइन इन करें
Topics पूर्ण चिह्नित करें, जहाँ छोड़ा था वहीं से जारी रखें और specialisation परीक्षाएँ खोलें।