- Roy Fielding के REST के मूल पेपर में HTTP methods या CRUD-केंद्रित API उपयोग को स्पष्ट रूप से अनिवार्य नहीं बताया गया है, और REST मूल रूप से hypermedia-based (HATEOAS) सिस्टम डिज़ाइन पर ज़ोर देता है
- जिन चीज़ों को बहुत से लोग RESTful API कहते हैं, वे अक्सर REST की महत्वपूर्ण constraints—खासकर hypermedia के उपयोग—को लागू नहीं करतीं
- Resource केवल साधारण data structure या entity तक सीमित नहीं है, बल्कि URI से पहचानी जा सकने वाली हर अवधारणा को शामिल करता है
- Fielding के 6 नियमों के अनुसार, hypermedia-केंद्रित navigation, protocol independence, और media type पर ज़ोर जैसी बातें मुख्य हैं
- व्यवहार में OpenAPI जैसी documentation tools की सुविधा के कारण ज़्यादातर API सचमुच RESTful होने के बजाय RPC style के अधिक करीब डिज़ाइन किए जाते हैं
ज़्यादातर RESTful API वास्तव में RESTful क्यों नहीं हैं
- Roy Fielding का प्रमुख पेपर (2000) REST (Representational State Transfer) को network-based software design की एक आदर्श शैली के रूप में प्रस्तुत करता है और इसे web की सफलता के पीछे की बुनियादी सोच के रूप में समझाता है
- इस पेपर में HTTP methods का उपयोग या CRUD-केंद्रित डिज़ाइन को अनिवार्य नहीं बताया गया है; REST का लक्ष्य रखते समय hypermedia (HATEOAS) आधारित state transition, universal interface, और resource-केंद्रित interaction को मुख्य माना गया है
Hypermedia (HATEOAS) और REST को लेकर गलतफहमियाँ
- Fielding ने स्पष्ट रूप से कहा है कि hypermedia के बिना API RESTful नहीं है
- "अगर engine hypertext द्वारा संचालित नहीं है, तो वह RESTful नहीं है"
- HATEOAS का मतलब है कि client, server response में शामिल links का अनुसरण करके dynamic तरीके से actions खोजता है
- केवल HTTP/CRUD interface का उपयोग करना REST के मूल सार से अलग है
REST के बारे में आम गलतफहमियाँ
- REST को CRUD समझना (जबकि वास्तव में यह इससे कहीं व्यापक अवधारणा है)
- यह मान लेना कि resource सिर्फ entity है (यानी server की data structure)
- यह दावा कि RESTful API में verb का उपयोग नहीं होना चाहिए
- ये बातें केवल design decisions हैं; इनका REST के मूल स्वरूप से सीधा संबंध नहीं है
Hypermedia-driven (HATEOAS) का वास्तविक अर्थ
- HATEOAS का उद्देश्य client-server coupling को न्यूनतम करना है
- जब server की URI structure बदलती है, तब client को दोबारा deploy करने की परेशानी कम करके scalability और evolvability बढ़ाई जा सकती है
- client बिना documentation या पूर्व-ज्ञान के response के भीतर मौजूद hyperlinks का अनुसरण करके व्यवहार खोजता है
{
"orderId": 123,
"_links": {
"self": { "href": "/orders/123" },
"cancel": { "href": "/orders/123/cancel", "method": "POST" }
}
}
- ऊपर की तरह, response में actions (links) शामिल होने चाहिए, तभी वह सचमुच RESTful के करीब माना जा सकता है
REST में resource क्या है?
- Resource वह सब कुछ है जिसे URI से पहचाना जा सके
- इसमें document, image, physical object, service, abstract concept आदि शामिल हैं
- server पर कोई वास्तविक "resource" वस्तु के रूप में मौजूद होना ज़रूरी नहीं; बस URI के माध्यम से उपलब्ध एक abstract mapping structure हो सकती है
- RFC 3986 भी resource की सीमा तय नहीं करता
- electronic document, image, information source, service, यहाँ तक कि व्यक्ति, संगठन, या पुस्तक भी इसमें आ सकते हैं
RESTful API के लिए Fielding द्वारा परिभाषित 6 नियम
- 1. किसी एक protocol पर निर्भर मत हो
- URI-based identification सभी protocols में उपयोग योग्य होनी चाहिए
- 2. Protocol (जैसे HTTP) standards को मनमाने ढंग से मत बदलो
- standards की कमियों की पूर्ति की जा सकती है, लेकिन अपने नियम जोड़ना या बदलना नहीं
- 3. URI structure के बजाय media type (format) की परिभाषा पर ध्यान दो
- data format और links की परिभाषा पर ध्यान दो; path specification/documentation पर अनावश्यक ऊर्जा बर्बाद मत करो
- 4. Fixed URI naming या hierarchy को hardcode मत करो
- client को server की namespace structure का अनुमान लगाने या उसे स्थिर मानने से बचाते हुए, link-based navigation की ओर ले जाना चाहिए
- 5. Resource type (internal classification) को expose मत करो
- internal object types client के लिए अर्थहीन हैं; केवल standard media type और links ही expose होने चाहिए
- 6. केवल bookmark (initial URI) की ज़रूरत हो; बाकी सब response के links से खोजो
- client को केवल standard media types पता होने चाहिए, और state transition हमेशा server response के hypermedia links के आधार पर होना चाहिए
नियमों की व्याख्या और वास्तविक उपयोग
- Protocol, URI, और type के साथ coupling को न्यूनतम करना ही वास्तविक RESTful होने के सबसे करीब ले जाता है
- API को data और links के format (media type) पर केंद्रित होना चाहिए; URI structure या naming conventions client को पहले से जानने की आवश्यकता नहीं होनी चाहिए
- उदाहरण के तौर पर,
/users/123/activate जैसे path को document करने के बजाय response में "activate" link देकर action बताना चाहिए
वास्तव में RESTful API कम क्यों मिलते हैं
- OpenAPI, Swagger जैसे tools की सुविधा को development में प्राथमिकता दी जाती है
- automatic documentation, code generation, validation जैसी व्यावहारिक सुविधाएँ मिलती हैं
- SPA environment में, जहाँ client और server एक ही टीम बनाती है, वहाँ URI coupling की समस्या उतनी गंभीर नहीं लगती, इसलिए HATEOAS के फायदे कम उभरते हैं
- REST principles को शुरू में सीखने का बोझ, dynamic link parsing की जटिलता जैसी व्यावहारिक बाधाएँ भी बड़ी हैं
निष्कर्ष
- Fielding के नियमों के अनुसार वास्तविक RESTful API के लिए hypermedia (HATEOAS) आधारित dynamic navigation अनिवार्य है
- REST केवल HTTP पर CRUD लागू करना नहीं है, बल्कि web के सिद्धांतों की तरह loose coupling, evolvability, और dynamic state transition पर केंद्रित एक architecture है
- व्यवहार में, व्यावहारिकता और टीम की स्थिति के अनुरूप डिज़ाइन अधिक महत्वपूर्ण हो सकता है
- अगर API external developers के लिए public है, तो HATEOAS अपनाना उपयोगी हो सकता है; लेकिन internal-only API के लिए सरल RPC style भी व्यावहारिक है
- API को सीखने में आसान और गलत उपयोग करना कठिन बनाना सबसे महत्वपूर्ण है; उसका अनिवार्य रूप से RESTful होना ज़रूरी नहीं
1 टिप्पणियां
Hacker News की राय
मुझे यहाँ दिखने वाला अत्यधिक मूलतत्त्ववाद समझ में आता है, और मैंने Fielding का पेपर भी रुचि से पढ़ा था, लेकिन मुझे लगा कि यह लड़ाई अब खत्म हो चुकी है। जैसे ही आप REST API शब्द सुनते हैं, आप लगभग यक़ीन से मान सकते हैं कि:
जैसी function बनाते हैं, और यह
को call करती है। Backend में
जैसी function होती है और annotation से URL mapping समझाई जाती है। अंत में यह RPC ही है। बस जटिल और गैर-स्वाभाविक system के बजाय यह थोड़ा ज़्यादा manual और developer-controlled रूप में बचा रह गया है। ज़्यादातर समस्याओं के 80% का कारण यह है कि लोग ISO 8601 date format का इस्तेमाल नहीं करते
मुझे समझ नहीं आता कि कोई इसे "लड़ाई" क्यों मानता है और इसकी परवाह क्यों करता है। REST की अवधारणा उपयोगी है, लेकिन HATEOAS वाला हिस्सा लगभग व्यावहारिक नहीं है और सिर्फ़ समस्याएँ पैदा करता है। Richardson maturity model को देखें तो REST की सबसे ऊँची अवस्था में HATEOAS जैसे तत्व शामिल हैं। यह तर्क भी समझ नहीं आता कि HATEOAS के बिना किसी चीज़ को REST नहीं कहा जा सकता, क्योंकि यह कोई बहुत बड़ा फर्क नहीं बनाता। अगर HATEOAS व्यावहारिक रूप से लगभग निरर्थक है, तो इस मूलतत्त्ववादी वर्गीकरण से चिपके रहने का कोई मतलब नहीं लगता। Richardson maturity model
"टीम status codes पर ज़रूरत से ज़्यादा बहस करती है और उन्हें HTTP spec से अलग तरह से इस्तेमाल करती है" वाली बात पर ज़ोर देते हुए: 401 Unauthorized तब इस्तेमाल होना चाहिए जब authentication न हुआ हो, और 403 Forbidden तब जब authorization न हो
मैं लोगों से पूछता हूँ कि क्या वे सच में REST का वही अर्थ इस्तेमाल करने वाले हैं जो paper में परिभाषित किया गया है। मैं आमतौर पर अर्थहीन terms के दुरुपयोग को स्वीकार नहीं करता। आख़िर में मैं बस कह देता हूँ, "अच्छा, मतलब एक web API की बात हो रही है," और आगे बढ़ जाता हूँ। असली फर्क यह है कि हर API की अपनी कुछ अजीबियाँ समझनी पड़ती हैं
मेरे लिए सच में महत्वपूर्ण nuance यह है कि "hypermedia links" अलग-अलग link types के रूप में "generic" लग सकते हैं, जो HTTP headers या response body में शामिल होते हैं, लेकिन व्यवहार में आज की REST भी उसी तरह काम करती है। उदाहरण के लिए, अगर खराब design के कारण "activate" की जगह "enable" होना चाहिए था, तो आखिरकार /api/v1/account/ID/activate को /api/v2/account/ID/enable में बदलना ही पड़ेगा। यानी API में हर action का अर्थ कहीं न कहीं hardcode करना ही पड़ता है (और icons, action description translations जैसी अतिरिक्त metadata की भी कमी होती है)। इस approach की "generality" वास्तव में एक भ्रम है
13 साल पहले जब मैंने पहली बार HTTP API develop किया, तो असली REST क्या है यह समझने के लिए Fielding का पेपर शुरू से अंत तक पढ़ा, और RESTful Web Services Cookbook भी पढ़ी। फिर Django की conventions से बचते हुए REST API बनाया। यह एक तरह का cargo cult approach था, क्योंकि मुझे ठीक से पता नहीं था कि असली REST हमारे service को क्या फायदा देगा। उसके बाद कई साल तक अलग-अलग HTTP APIs बनाते हुए अंततः मुझे महसूस हुआ कि व्यावहारिक काम में REST के शुद्ध सिद्धांत कोई खास लाभ नहीं देते। "self-discovery" और "generic clients के साथ compatibility" वाला vision लगभग असंभव है, और खास तौर पर Fielding का पेपर इन बातों के लिए पूरी तरह मार्गदर्शन भी नहीं देता। सच में self-discoverable API बनाने के लिए "endpoint discovery protocol", "operation description", "help messages" जैसी ठोस rules चाहिए। और अंत में उन rules को समझने वाला dedicated client बनाना पड़ता है, तो generalized client का फायदा खत्म हो जाता है। यानी व्यवहार में service-specific API/JS code/CLI आदि के लिए आखिरकार server-specific custom code लिखना ही पड़ा। और अच्छी UX, REST के आदर्शों से टकराती है, क्योंकि सच में अच्छी UX देने के लिए frontend में app-specific code चाहिए। UI elements को standardize किया जा सकता है, लेकिन व्यवहार में JavaScript जैसी भाषाओं से flexible UI बनाना ज़्यादा उपयोगी है
self-discoverable API की अवधारणा की सीमाओं से मैं सहमत हूँ। असली REST client व्यवहार में बन ही नहीं सकता। उसे हर URL के व्यवहार का पता होना चाहिए, और अगर कोई नया behavior जुड़ जाए (जैसे /cansofspam/123/frobnicate), तो client उसे स्पष्ट रूप से handle नहीं कर पाएगा। आखिर में या तो client update करना पड़ेगा, या उसे ignore करना होगा, या बस एक बहुत साधारण button (जैसे Frobnicate) जोड़ना होगा। इसलिए पूरी तरह के अर्थ में REST server या client वास्तव में मौजूद नहीं हैं। व्यवहार में वही API चल पाती है जिसकी client पहले से उम्मीद करता है, बिना discovery के
APIs के कई पहलू होते हैं, इसलिए उन्हें समझाना कठिन है। API consumers को average response latency, retry किए जा सकने वाले error codes, action की atomicity/idempotency जैसी बातें भी जाननी होती हैं। HATEOAS अकेले यह सब नहीं बता सकता। perfect REST implement करने की ज़रूरत नहीं है, और मूल रूप से REST का फायदा सिर्फ़ इतना है कि nouns/verbs को HTTP methods और URLs से map करने की एक साझा भाषा मिल जाती है। फिर भी detail-level design और सोच-विचार बहुत ज़्यादा है। उदाहरण के लिए, जो चीज़ HTTP spec में allowed है, वह वास्तविक LB में usable न हो, या 500 errors पर retry criteria/backoff logic जैसी चीज़ों पर ध्यान देना पड़े
browser ही असली "generic code" है, और वही हमें रोज़ का सबसे अच्छा UX देता है। REST की अवधारणा में यह भी शामिल है कि server client को code दे सकता है (हालाँकि security issues हैं, लेकिन browser और standards ने इसमें भी बहुत कुछ हल किया है)। Fielding पेपर में संबंधित भाग का लिंक
सच कहें तो REST की कमजोर परिभाषा में भी कोई खास फायदा नहीं है। "resource delete करने के लिए DELETE ही इस्तेमाल करना चाहिए" जैसी बात बहुत महत्वपूर्ण नहीं है। बस POST इस्तेमाल करें तो किसे दिक्कत होती है?
मैंने कभी यह नहीं माना कि 'self-discoverable' कोई लक्ष्य है, और न ही यह कि इसे हासिल किया जा सकता है। सरल client design के लिए यह शुरुआत से ही बहुत ज़्यादा अपेक्षा है। खासकर, TFA में तो ‘discoverable’ शब्द आता ही नहीं
इस तरह की API design वास्तव में तब उपयोगी होती है, जब user और उसकी ओर से explore करने वाला agent (जैसे browser) API को browse कर सके और हर response में media type, link information के आधार पर interact कर सके। ज़्यादातर web APIs ऐसे use-case के लिए नहीं, बल्कि एक खास UI/UX वाले web app के लिए design की जाती हैं। यह एक जानबूझकर चुनी गई दिशा है। App बनाने वाला अपने लक्ष्य के लिए data representation, UI flow आदि पर पूरा control चाहता है। REST API design तब ज़रूरी होती है जब user को API resources के इस्तेमाल के तरीके पर ज़्यादा नियंत्रण चाहिए। उदाहरण:
वास्तव में HTML document ठीक वही उदाहरण है। Document के भीतर दूसरे documents की links होती हैं, और user link पर लिखे text के आधार पर कहीं भी जा सकता है। अगर यह users के लिए है तो हम इसे UI कहते हैं, और अगर applications के लिए है तो API। HATEOAS अजीब इसलिए लगता है क्योंकि यह मानो API को सीधे user-facing बनाना चाहता है। लेकिन हम यह चीज़ पहले से UI के रूप में पा ही रहे हैं
शुद्ध REST की अवधारणा बहुत अकादमिक है। open/big data projects में वास्तविक performance या architecture लागू करने के लिए REST हासिल हुआ या नहीं, उससे ज़्यादा व्यावहारिक approach महत्वपूर्ण है। यहाँ तक कि अकादमिक लोग भी आखिरकार कुछ deliver करना चाहते हैं, इसलिए वे सिर्फ़ perfect REST पर अड़े नहीं रहते
इस तरह की API design सिर्फ़ web pages ही नहीं, दूसरे clients बनाने में भी उपयोगी है। GET से resource लेना, fields/paths से values निकालना, नया URI बनाकर manipulate करना—ऐसे समान patterns से कई तरह के apps/CLI/UI बनाए जा सकते हैं। अगर non-SPA है तो HTML से सीधे implement करना भी संभव है। अंततः user (या user-agent) returned representation के अंदर की जानकारी को dereference कर रहा होता है
सोचता हूँ कि जब AI APIs consume करने लगेगा, तब यह use-case और महत्वपूर्ण हो जाएगा या नहीं। API की discoverability, web app developers की तुलना में AI के लिए कहीं ज़्यादा फायदेमंद है। MCP (Immersive Control Protocol) को देखें तो tool discoverability कितनी शक्तिशाली है यह पता चलता है। HATEOAS, ऐसे bare API consumption में भी बड़ा संभावित लाभ दे सकता है
अमेरिकी राष्ट्रीय मौसम सेवा के RESTful service API docs जैसे public information APIs अगर अच्छी तरह design किए जाएँ, तो उनका इस्तेमाल सच में बहुत सुखद होता है
"सचमुच hypermedia-based client बनाने की शुरुआती cognitive load बहुत भारी लगी, और बस URI templates (/users/{id}/orders आदि) hardcode करना ज़्यादा आसान लगा"—इससे जुड़ी बात पर, अनुभव से यही महसूस हुआ कि वह वास्तव में आसान है। शुद्ध REST principles ज़्यादातर स्थितियों में cost-benefit के हिसाब से कमजोर हैं। जैसे microwave में एक ही button से menu/operation/time सब कुछ control करना, साधारण standard buttons को आदत से इस्तेमाल करने की तुलना में कहीं ज़्यादा झंझट भरा होता है। जो 2-button engine code reader मैं वास्तव में इस्तेमाल करता हूँ, उसका operation भी हास्यास्पद रूप से असुविधाजनक है। अब भी Fielding का पेपर ज़रूर पढ़ना चाहिए—ऐसी संस्कृति कुछ ज़्यादा ही विवादास्पद है। अगर कोई idea अच्छा है, तो उसे कई तरीकों से, लोकप्रिय दृष्टिकोण से, आसानी से समझाया जा सकना चाहिए। उदाहरण के लिए, physics समझने के लिए कोई यह नहीं कहता कि Newton की Principia ज़रूर पढ़ो
RESTful/HATEOAS patterns अपनाने में तब ही वास्तविक मूल्य है, जब उन्हें समझने वाले clients मौजूद हों। htmx: hypermedia clients intercoolerjs: hatoeas-is-for-humans
UI designers screen के बारीक look को control करना चाहते हैं। Resource पर संभव कुछ actions बड़े buttons के रूप में दिखाना चाहते हैं, कुछ को menu में छिपाना चाहते हैं, और कुछ को UI में बिल्कुल नहीं दिखाना चाहते। अगर actions हर state के अनुसार API response के आधार पर dynamically render हों, तो सारे actions एक जैसे दिखने लगेंगे। इसलिए मुझे लगता है कि RESTful APIs आम web frontend UI implementation के लिए उपयुक्त नहीं हैं
इस दावे में कई गलतियाँ हैं
मेरे अनुभव में, "RESTful API" develop करना बहुत कम बार सीधे UI से जुड़ा होता है। अगर सिर्फ़ वास्तविक UI चाहिए, तो API की ज़रूरत ही नहीं है—बस server-driven approach (जैसे पुराने DWR) से भी काम हो सकता है
HATEOAS व्यवहार में लगभग इस्तेमाल ही नहीं होता, फिर भी इस पर इतनी चर्चा क्यों होती है, यह समझ नहीं आता। क्या सच में कोई इसे इस्तेमाल करता है, और क्या वास्तव में ऐसा कोई "auto-discovery client" है जिसे server की जानकारी पहले से न पता हो?
याद दिलाना चाहूँगा कि ACME (Let’s Encrypt का protocol) HATEOAS-आधारित है। यह व्यवहार में ज़्यादातर HTTPS services में इस्तेमाल होता है। HTTP खुद भी, अगर उसे सही तरह इस्तेमाल किया जाए, तो HATEOAS protocol है। "auto-discovery" का मतलब links types या ‘next’ जैसी चीज़ों से resources को explore करना है। हाँ, client को "next" का अर्थ पहले से पता होना चाहिए। LLMs भी इस तरह की automatic exploration में अच्छे हैं
मैंने enterprise-grade video surveillance system में HATEOAS का उपयोग किया था। इसने versions/permissions की समस्याओं को API level पर शानदार तरीके से हल किया। कई RFCs भी साथ में इस्तेमाल किए। लेकिन सबसे बड़ी समस्या यह थी कि लोग "सुविधा" के नाम पर model को तोड़ने की दिशा में जाते हैं और उल्टा complexity बढ़ा देते हैं। फिर JSON स्वभाव से hypertext format नहीं है, इसलिए application/json में HATEOAS को ठूँसने की कोशिश थोड़ी बनावटी लगती थी
मैं HATEOAS का इस्तेमाल करके comments लिख रहा हूँ, और अभी इसी समय reply भी कर रहा हूँ। इस सबको संभालने वाला "जादुई auto-discovery client" दरअसल "web browser" ही है
htmx शायद सबसे व्यावहारिक कोशिश हो सकती है
OData जैसे standards भी लगभग इस्तेमाल नहीं होते, और वैसे भी बहुत popular नहीं हैं। HATEOAS में तो popularity/standards दोनों की कमी है, इसलिए शायद यह और भी कम फैलता है
इस चर्चा में हमेशा छूट जाने वाली चीज़ backend API consumer का प्रकार है। REST और HATEOAS का महत्व आमतौर पर तब बढ़ता है जब consumer वह third party हो जो backend को सीधे own नहीं करती। उदाहरण के लिए, पारंपरिक HTML page का अंतिम consumer browser user होता है। हाल का MCP भी ऐसे cases के लिए आया है जहाँ विभिन्न JSON RPC APIs के लिए "discovery और interpretation" की ज़रूरत होती है। दूसरी ओर, जब frontend और backend 1:1 tightly coupled हों, तो REST का लाभ उसकी लागत के अनुपात में बड़ा नहीं होता। ज़्यादा generic documentation/specification बनानी पड़ती है, और व्यवहार में separation of concerns को अनदेखा करके productivity बढ़ाने वाले tools (जैसे trPC) ज़्यादा उपयोगी हो सकते हैं। Prototype के समय end-to-end integration तेज़ होती है
पूरी तरह सहमत हूँ, और HATOEAS is for humans htmx: hypermedia clients लेखों की सिफारिश करता हूँ
*HATEOAS
HATEOAS और schema reference (XSD, JSON Schema आदि) से dynamic exploration clients संभव होने के दावे पर, व्यवहार में JSON schema की "additionalProperties" जैसी सुविधाएँ फिर उसी मूल समस्या को दोहराती हैं। मुझे लगता है कि "out of band" तरीके से documentation देना ज़्यादा robust है। तो फिर अगर "_links" में सिर्फ़ Swagger docs की एक link दे दी जाए, और client उस self path information को समझ ले, तो क्या होगा? अगर ऐसा ही करना है, तो "_links" की ज़रूरत ही क्यों है? अगर कोई client इतने जटिल JSON documents संभाल सकता है, तो Swagger templates वगैरह से कहीं ज़्यादा information density और dynamism मिल सकता है। सिर्फ़ CRUD links से पूरे API को ठीक से समझाना पर्याप्त नहीं है, और JSON schema से सब कुछ cover करना भी संभव नहीं
इसे बस HTTP API कहें तो सब खुश रहेंगे। REST मूल रूप से API के लिए design ही नहीं किया गया था। शुरुआत से ही REST इंसानों के लिए information systems के बारे में था, programs के लिए नहीं था