API रिक्वेस्ट बनाना
API request बनाने का मतलब है API documentation को एक सटीक HTTP message में बदलना: एक method, एक URL, और हर input उसी जगह जहाँ API उसकी उम्मीद करता है — path, query string, कोई header या body — उसी encoding में जो API बताता है। गलत जगह रखी value को server अनदेखा कर सकता है, या वह server का व्यवहार ही बदल सकती है।
उदाहरण के लिए, "customer 58 के paid orders, page 2" बनता है GET /api/v1/customers/58/orders?status=paid&page=2, बिना body के। "उसी customer के address 3 की city बदलो" बनता है PATCH /api/v1/customers/58/addresses/3, Content-Type: application/json और body {"city": "Jeddah"} के साथ।
यह क्यों ज़रूरी है
गलत बनी request कुछ टेस्ट नहीं करती, या कुछ और टेस्ट कर देती है। GET की body में filter रखें, तो कई servers उसे अनदेखा करके पूरी list लौटा देते हैं; "list load होती है" वाला check pass हो जाता है, जबकि filter कभी टेस्ट ही नहीं हुआ। Search term के अंदर & को encode किए बिना छोड़ दें, तो server को एक की जगह दो parameters मिलते हैं।
Request के हर हिस्से पर नियंत्रण असली defects को पकड़ना भी आसान बनाता है: आप एक बार में एक input बदलते हैं, user interface के बिना bug reproduce करते हैं, और developers को ऐसी request देते हैं जिसे वे ख़ुद चला सकें।
Input रखने की चार जगहें
शुरुआत API reference से करें। कई teams इसे OpenAPI document के रूप में publish करती हैं: REST API का एक standard, machine-readable विवरण, जो YAML या JSON में लिखा जाता है। इसमें हर parameter का एक in field होता है जो उसकी जगह बताता है, जैसे path, query या header; body का वर्णन requestBody के नीचे होता है। नीचे दिया excerpt worked example वाला endpoint है।
- Path parameters resource की पहचान करते हैं, जैसे
/customers/{customerId}में{customerId}। ये हमेशा required होते हैं; पूरा placeholder, braces समेत, बदलें। - Query parameters request को refine करते हैं: filter, sort, page, search या कोई option चालू-बंद करना। ये आम तौर पर optional होते हैं और इनका default होता है, इसलिए किसी एक को छोड़ देना भी एक test case है। Values के अंदर reserved characters को percent-encode करें।
- Headers request का वर्णन करते हैं:
Content-Typeबताता है कि body क्या है,Acceptकि जवाब में क्या चाहिए,Authorizationकि call कौन कर रहा है। OpenAPI इन तीनों को parameters में नहीं लिखता; येrequestBody, responses औरsecurityसे तय होते हैं। - Body में वह data होता है जिसे आप बनाते या बदलते हैं। RFC 9110 के अनुसार GET या DELETE request के content का कोई आम तौर पर परिभाषित अर्थ नहीं है, इसलिए इन requests में आम तौर पर body नहीं होती।
# server: https://api.example.com/api/v1
/customers/{customerId}/addresses/{addressId}:
patch:
parameters:
- name: customerId
in: path
required: true
schema: { type: integer }
- name: addressId
in: path
required: true
schema: { type: integer }
- name: notify
in: query
required: false
description: Send the customer an SMS about the change
schema: { type: boolean, default: true }
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/AddressChange' }
responses:
'200':
description: The updated address
content:
application/json:
schema: { $ref: '#/components/schemas/Address' }
security:
- bearerAuth: []Request body: JSON, form और multipart
Content-Type header को वही bytes बताने चाहिए जो आप सच में भेज रहे हैं। तीन formats ज़्यादातर APIs को cover करते हैं; नीचे का sample हर format में वही rating भेजता है।
application/json: REST APIs का आम format। यह types बनाए रखता है —4number है,"4"string — और objects व arrays को nest कर सकता है।application/x-www-form-urlencoded(WHATWG URL Standard): पारंपरिक HTML form का format —&से जुड़ेname=valuepairs, percent-encoded, और space की जगह+। हर value text होती है। कुछ login और token endpoints अब भी यही माँगते हैं।multipart/form-data(RFC 7578): file upload के लिए। Parts एक boundary से अलग होते हैं जोContent-Typeमें declare होती है; इसे client को generate करने दें, क्योंकि boundary के बिना हाथ से लिखाmultipart/form-dataserver parse नहीं कर सकता।- जो format endpoint स्वीकार नहीं करता, उसे reject होना चाहिए, आम तौर पर
415 Unsupported Media Typeके साथ — यह एक उपयोगी negative test है।
POST /api/v1/stores/riyadh-01/feedback HTTP/1.1
Host: api.example.com
Content-Type: application/json
{"rating": 4, "subscribe": true}
POST /api/v1/stores/riyadh-01/feedback HTTP/1.1
Host: api.example.com
Content-Type: application/x-www-form-urlencoded
rating=4&subscribe=true
POST /api/v1/stores/riyadh-01/feedback HTTP/1.1
Host: api.example.com
Content-Type: multipart/form-data; boundary=x7Kq9
--x7Kq9
Content-Disposition: form-data; name="rating"
4
--x7Kq9
Content-Disposition: form-data; name="photo"; filename="box.jpg"
Content-Type: image/jpeg
(the bytes of the image)
--x7Kq9--आज़माएँ: API पेलोड बिल्डर आज़माएँ: रिक्वेस्ट बॉडी इंस्पेक्टर
Worked example: contract से request तक
एक test case कहता है: test customer 58 के address 3 की city Jeddah और postal code 23436 करें, customer को SMS भेजे बिना। ऊपर वाले excerpt पर एक-एक input लेकर काम करें।
- Method: contract इस path के लिए
patchपरिभाषित करता है — यानी आंशिक बदलाव। - Path: server URL, फिर दोनों placeholders बदलकर path:
/api/v1/customers/58/addresses/3। - Query:
notifySMS भेजता है और उसका defaulttrueहै, इसलिए इसे छोड़ने पर SMS चला जाएगा;?notify=falseजोड़ें। - Headers:
requestBodyसेContent-Type: application/json, response सेAccept: application/json, औरsecurityसेAuthorization, test account के bearer token के साथ। - Body: सिर्फ़ बदले हुए fields, उन्हीं types में जो schema तय करता है।
$refdocument में कहीं और लिखेAddressChangeschema की ओर इशारा करता है, जोcityऔरpostalCodeको string परिभाषित करता है, इसलिए postal code quotes में जाता है:{"city": "Jeddah", "postalCode": "23436"}। - Variants: एक बार में एक हिस्सा बदलें —
postalCodeको number के रूप में भेजें, किसी दूसरे customer का address लें,Content-Typeहटाएँ — ताकि हर नतीजा एक ही input की ओर इशारा करे।
रिक्वेस्ट
भाग 1:PATCH /api/v1/customers/भाग 2:58/addresses/भाग 2:3?भाग 3:notify=false HTTP/1.1 भाग 4:Host: api.example.com भाग 5:Content-Type: application/json Accept: application/json भाग 6:Authorization: Bearer eyJhbGciOi... भाग 7:{"city": "Jeddah", "postalCode": "23436"}
- 2–3Contract में
parametersके नीचे declare - 5–7
requestBody, responses औरsecurityसे तय
- 1मेथडContract इस path के लिए
patchपरिभाषित करता है: आंशिक बदलाव। - 2Path पैरामीटर
58और3,{customerId}और{addressId}की जगह लेते हैं; दोनों required हैं। - 3Query पैरामीटरOptional, default
true;falseरखें ताकि test कोई SMS न भेजे। - 4सर्वर (base URL)Contract के server URL का host; उसका path
/api/v1request path की शुरुआत है। Base URL को हर environment के लिए variable में रखें। - 5फ़ॉर्मेट headers
Content-Type: body JSON है।Accept: जवाब JSON में चाहिए। - 6क्रेडेंशियलTest account का bearer token, header में — URL में कभी नहीं।
- 7बॉडीसिर्फ़ बदले हुए fields, JSON में; postal code string है।
पाठ संस्करण
PATCH /api/v1/customers/58/addresses/3?notify=false HTTP/1.1
Host: api.example.com
Content-Type: application/json
Accept: application/json
Authorization: Bearer eyJhbGciOi...
{"city": "Jeddah", "postalCode": "23436"}आज़माएँ: API क्वेरी पैरामीटर बिल्डर आज़माएँ: API हेडर बिल्डर
API client से request भेजना
Graphical API client — Postman, या browser में Mutqan का API रिक्वेस्ट बिल्डर — इन फ़ैसलों को fields में बदल देता है: method, URL, parameters की table, headers की table, authorisation और body editor। cURL, जो एक command-line client है, इन्हें -X, -H और -d जैसे options में बदलता है। Tool से ज़्यादा ये आदतें मायने रखती हैं:
- Base URL, test account और token को variables में रखें (Postman इन्हें
{{baseUrl}}लिखता है), ताकि एक ही saved request हर environment पर चले। - Query parameters table में डालें और body type चुनें, ताकि client query string बनाए और
Content-Typeset करे; अगर वह header हाथ से भी लिखें, तो दोनों का मेल पक्का करें। अलग-अलग clients अलग-अलग characters encode करते हैं, इसलिए जाँचें किtea & coffeeजैसी value एक ही parameter बनकर पहुँचे। - जाँचें कि असल में क्या भेजा गया: clients ऐसे headers जोड़ते हैं जो आपने नहीं लिखे, जैसे
User-Agent। Request एक बार Mutqan के HTTP रिक्वेस्ट इंस्पेक्टर के capture URL पर भेजें और तुलना करें। - Bug reports के लिए request को cURL के रूप में export करें, token की जगह
$TOKENजैसा shell variable रखकर। Sample में bash वाली quoting है; Mutqan का cURL जनरेटर PowerShell और Windows cmd के versions भी लिखता है। - cURL में
-dbody भेजता है और method को POST बना देता है, जब तक-Xकोई दूसरा method न बताए;Content-Typeheader के बिना वह body कोapplication/x-www-form-urlencodedबताकर भेजता है, चाहे वह JSON ही क्यों न हो।
curl -X PATCH "https://api.example.com/api/v1/customers/58/addresses/3?notify=false" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"city": "Jeddah", "postalCode": "23436"}'आज़माएँ: API रिक्वेस्ट बिल्डर आज़माएँ: cURL जनरेटर आज़माएँ: HTTP रिक्वेस्ट इंस्पेक्टर
आम गलतियाँ
- Filters या search terms को query string की जगह GET request की body में रखना।
- URL में query values को percent-encode किए बिना लिखना, जैसे
+, जिसे कई servers space पढ़ते हैं; क्या encode करना है, यह URL, पाथ और क्वेरी पैरामीटर वाला lesson बताता है। Content-Type: application/jsonके बिना JSON भेजना, या boundary के बिना हाथ सेmultipart/form-dataलिखना।- जिन numbers और booleans को schema number या boolean परिभाषित करता है, उन्हें quotes में भेजना (
"4","true")। - Optional parameters के defaults जाने बिना उन्हें छोड़ देना: छूटा हुआ
notifyकिसी test से असली messages भेज सकता है।
QA का नज़रिया
आप तीन मौकों पर requests बनाते हैं। Review में: अगर सिर्फ़ documentation से valid request नहीं बन पाती, तो documentation में defect है। Testing में: हर scenario के लिए एक saved request, environment और data के लिए variables के साथ। Bug report में: वही exact request cURL के रूप में, token हटाकर।
Contract जो बातें खुली छोड़ता है, उनके बारे में developers से जल्दी पूछें — correlation id जैसे required headers, जो request को server logs से जोड़ता है, हर optional parameter का default, lists repeated keys से जाती हैं या commas से — और जवाब saved requests (जैसे Postman collection) या test case में दर्ज करें।
अभ्यास
API reference से दो requests बनाएँ
नीचे दिए reference से दो requests बनाएँ: (1) store riyadh-01 में categories drinks और gifts के अंदर "tea & coffee" खोजें, सबसे सस्ता पहले, यानी वही search जिसे आपने URL, पाथ और क्वेरी पैरामीटर वाले lesson में encode किया था, अब पूरी request के रूप में; (2) उसी store के product 9917 के लिए comment "Fresh, well packed" के साथ 4-star review post करें।
हर request को raw HTTP और cURL, दोनों रूपों में लिखें। चाहें तो HTTP रिक्वेस्ट इंस्पेक्टर में एक capture URL बनाएँ, उसे base URL की जगह लगाकर दोनों requests वहाँ भेजें (dummy token के साथ, कोई असली personal data नहीं) और जो पहुँचा उसकी तुलना करें।
Base URL: https://api.example.com/api/v1
Every call: Authorization: Bearer <token>
GET /stores/{storeId}/products
storeId path string required
q query string optional free-text search
category query string optional repeat the key for several values
sort query string optional price_asc | price_desc (default: relevance)
Response: application/json
POST /stores/{storeId}/products/{productId}/reviews
storeId path string required
productId path integer required
Body: application/json
rating integer required 1 to 5
comment string optional up to 500 characters- Task के हर input की जगह reference में खोजें: path, query, header या body।
- Method और URL लिखें, query values को encode करते हुए।
- हर request को जिन headers की ज़रूरत है सिर्फ़ वही जोड़ें, और जहाँ हो वहाँ body।
- हर request को cURL में बदलें और raw version से मिलाएँ।
मॉडल उत्तर दिखाएँ
Request 1, raw HTTP में: GET /api/v1/stores/riyadh-01/products?q=tea%20%26%20coffee&category=drinks&category=gifts&sort=price_asc HTTP/1.1, Host: api.example.com, Accept: application/json और Authorization के साथ; कोई body नहीं और कोई Content-Type नहीं। Query वही encoded search है जो URL वाले lesson में बना था; इस request में नया है headers का चुनाव: Accept क्योंकि reference JSON response बताता है, Authorization क्योंकि हर call को इसकी ज़रूरत है, और body का वर्णन करने वाला कुछ नहीं। कोई client spaces को + लिख सकता है (q=tea+%26+coffee), जो form encoding का तरीका है; जो server query को form data की तरह पढ़ता है, वह इसे भी उसी value में decode करता है।
Request 2, raw HTTP में: POST /api/v1/stores/riyadh-01/products/9917/reviews HTTP/1.1, Host, Content-Type: application/json, Accept और Authorization के साथ, और body {"rating": 4, "comment": "Fresh, well packed"} — 4 number के रूप में, string "4" नहीं।
Request 1 का cURL: curl "https://api.example.com/api/v1/stores/riyadh-01/products?q=tea%20%26%20coffee&category=drinks&category=gifts&sort=price_asc" -H "Accept: application/json" -H "Authorization: Bearer $TOKEN"। URL quotes में रखें, वरना shell & को अपना operator मान लेता है। GET default method है, इसलिए -X की ज़रूरत नहीं।
Request 2 का cURL: curl "https://api.example.com/api/v1/stores/riyadh-01/products/9917/reviews" -H "Content-Type: application/json" -H "Accept: application/json" -H "Authorization: Bearer $TOKEN" -d '{"rating": 4, "comment": "Fresh, well packed"}'। -d अपने आप method को POST बना देता है, इसलिए -X POST optional है; Content-Type header cURL को JSON को form data बताने से रोकता है।
Inspector में query decode होकर q = "tea & coffee" और category की दो values दिखनी चाहिए, और review body valid JSON के रूप में parse होनी चाहिए।
अक्सर पूछे जाने वाले सवाल
OpenAPI reference कैसे बताता है कि query में list कैसे भेजनी है?
Parameter के style और explode से। Query parameter का default style: form के साथ explode: true है, जो key को दोहराता है: ?category=drinks&category=gifts। explode: false के साथ values commas से जुड़ती हैं: ?category=drinks,gifts। अगर parameter इनमें से कुछ भी set न करे, तो यही defaults लागू होते हैं। Exercise जैसा plain-text reference इसे शब्दों में लिखता है ("repeat the key"); अगर कुछ न लिखा हो तो पूछें, क्योंकि servers अलग-अलग होते हैं।
जब reference और server अलग-अलग बात कहें, तो क्या करूँ?
अपने-आप किसी को न मानें: यह अंतर ही आपकी finding है। Reference से बनी request, response और reference का text दर्ज करें, और team से पूछें कि इरादा कौन-सा है। फिर या तो server ठीक होता है या reference सुधारा जाता है; उसके बाद ही अपनी saved request बदलें, ताकि वह contract को टेस्ट करती रहे, न कि server आज जो करता है उसे।
Request body JSON हो या form-encoded?
वही जो contract उस endpoint के लिए declare करता है। ज़्यादातर REST APIs application/json की उम्मीद करती हैं; HTML form posts और कुछ token endpoints application/x-www-form-urlencoded चाहते हैं; file uploads में multipart/form-data इस्तेमाल होता है। Content-Type header भेजी गई body से मेल खाना चाहिए।
Copy किया हुआ cURL command Windows पर fail क्यों होता है?
हर shell में quoting के नियम अलग हैं। इस lesson का bash version JSON body को single quotes में रखता है, जिन्हें Windows cmd quotes नहीं मानता, इसलिए command टूट जाता है। Windows PowerShell 5.1 में curl, Invoke-WebRequest का alias है, जो cURL के options स्वीकार नहीं करता; उसकी जगह curl.exe लिखें। Mutqan का cURL जनरेटर उसी request को PowerShell और cmd के लिए भी लिखता है।
संदर्भ
- RFC 9110: HTTP SemanticsHTTP मेथड, हेडर फ़ील्ड, स्टेटस कोड और कंटेंट निगोशिएशन के अर्थ, वायर वर्ज़न से स्वतंत्र।
- OpenAPI SpecificationREST API के वर्णन का मानक: पाथ, ऑपरेशन, पैरामीटर, स्कीमा, रिस्पॉन्स और सिक्योरिटी स्कीम।
- URL Standardब्राउज़र वास्तव में URL को कैसे पार्स, सीरियलाइज़ और एन्कोड करते हैं, application/x-www-form-urlencoded सहित।
- RFC 7578: Returning Values from Forms: multipart/form-dataफ़ाइल अपलोड और मिश्रित फ़ॉर्म सबमिशन के लिए इस्तेमाल होने वाली multipart/form-data एन्कोडिंग।
Mutqan tools से अभ्यास करें
HTTP रिक्वेस्ट (method, URL, हेडर, auth, बॉडी) बनाएँ और भेजें, फिर रिस्पॉन्स जाँचें — आपके ब्राउज़र में हल्का-फुल्का Postman।
मेथड, URL, हेडर, बॉडी और auth विकल्पों से cURL कमांड बनाएँ।
API कॉल के लिए pagination, filtering और sorting पैरामीटर के साथ सही एन्कोड की गई क्वेरी स्ट्रिंग बनाएँ।
REST API के लिए रिक्वेस्ट हेडर (auth, content negotiation, tracing) बनाएँ और cURL, fetch, axios या HTTP में एक्सपोर्ट करें।
विज़ुअल फ़ील्ड एडिटर से JSON रिक्वेस्ट बॉडी बनाएँ और भेजने से पहले उन्हें जाँचें।
देखें कि आपका क्लाइंट असल में क्या भेजता है: method, हेडर, query, बॉडी, IP और TLS जानकारी।
और गहराई से
इस topic में आपकी प्रगति
प्रगति ट्रैक करने के लिए साइन इन करें
Topics पूर्ण चिह्नित करें, जहाँ छोड़ा था वहीं से जारी रखें और specialisation परीक्षाएँ खोलें।