आरईएस नेस्टेड संसाधनों के लिए सर्वोत्तम अभ्यास क्या हैं?


301

जहां तक ​​मैं बता सकता हूं प्रत्येक व्यक्ति के संसाधन में केवल एक विहित मार्ग होना चाहिए । तो निम्न उदाहरण में अच्छा URL पैटर्न क्या होगा?

एक उदाहरण के लिए कंपनियों का एक बाकी प्रतिनिधित्व ले लो। इस काल्पनिक उदाहरण में, प्रत्येक कंपनी के पास 0 या अधिक विभाग हैं और प्रत्येक विभाग के पास 0 या अधिक कर्मचारी हैं।

एक संबद्ध कंपनी के बिना एक विभाग मौजूद नहीं हो सकता

एक कर्मचारी संबंधित विभाग के बिना मौजूद नहीं हो सकता

अब मुझे होने वाले संसाधन पैटर्न का स्वाभाविक प्रतिनिधित्व मिलेगा।

  • /companies कंपनियों का एक संग्रह - एक नई कंपनी के लिए स्वीकार किए जाते हैं। पूरे संग्रह के लिए जाओ।
  • /companies/{companyId}एक व्यक्तिगत कंपनी। GET, PUT और DELETE को स्वीकार करता है
  • /companies/{companyId}/departmentsनए आइटम के लिए POST स्वीकार करता है। (कंपनी के भीतर एक विभाग बनाता है।)
  • /companies/{companyId}/departments/{departmentId}/
  • /companies/{companyId}/departments/{departmentId}/employees
  • /companies/{companyId}/departments/{departmentId}/employees/{empId}

बाधाओं को देखते हुए, प्रत्येक अनुभाग में, मुझे लगता है कि यह समझ में आता है अगर थोड़ा गहराई से घोंसला बनाया जाए।

हालाँकि, मेरी कठिनाई तब होती है जब मैं GETसभी कंपनियों के सभी कर्मचारियों को सूचीबद्ध करना चाहता हूं ।

इसके लिए संसाधन पैटर्न सबसे नज़दीकी नक़्शा /employees(सभी कर्मचारियों का संग्रह)

क्या इसका मतलब यह है कि मुझे /employees/{empId}भी होना चाहिए क्योंकि यदि ऐसा है तो एक ही संसाधन प्राप्त करने के लिए दो यूआरआई हैं?

या हो सकता है कि पूरे स्कीमा को चपटा किया जाए लेकिन इसका मतलब यह होगा कि कर्मचारी एक नेस्टेड टॉप-लेवल ऑब्जेक्ट हैं।

एक बुनियादी स्तर /employees/?company={companyId}&department={deptId}पर कर्मचारियों के सबसे गहन नेस्टेड पैटर्न के रूप में सटीक दृश्य देता है।

URL पैटर्न के लिए सबसे अच्छा अभ्यास क्या है जहाँ संसाधन अन्य संसाधनों के स्वामित्व में हैं, लेकिन अलग से क्वेरी-सक्षम होना चाहिए?


1
यह लगभग बिल्कुल अप्सपीट की समस्या है जिसका वर्णन stackoverflow.com/questions/7104578/… में किया गया है, हालांकि उत्तर संबंधित हो सकते हैं। दोनों प्रश्न स्वामित्व के बारे में हैं, लेकिन इसका उदाहरण यह है कि शीर्ष स्तर की वस्तु का मालिक नहीं है।
वेस

1
वास्तव में मैं क्या सोच रहा था। दिए गए उपयोग के मामले में आपका समाधान ठीक लगता है, लेकिन क्या होगा यदि संबंध एक रचना के बजाय एक एकत्रीकरण है? अभी भी यह पता लगाने के लिए संघर्ष कर रहा है कि सबसे अच्छा अभ्यास यहां क्या है ... इसके अलावा, क्या यह समाधान केवल संबंध बनाने का काम करता है, जैसे कि एक मौजूदा व्यक्ति कार्यरत है या यह एक व्यक्ति वस्तु बनाता है?
जैकब ओ।

यह एक व्यक्ति को मेरे काल्पनिक उदाहरण में बनाता है। मेरे द्वारा उन डोमेन शब्दों का उपयोग करने का कारण इसकी यथोचित समझ है, हालांकि मेरी वास्तविक समस्या की नकल है। क्या आपने लिंक किए गए प्रश्न के माध्यम से देखा है जो आपको एक aggragation रिश्ते के लिए और अधिक रोक सकता है।
वेस

मैंने अपने प्रश्न को एक उत्तर और एक प्रश्न में विभाजित किया है।
वेस

जवाबों:


152

आपने जो किया है वह सही है। सामान्य तौर पर एक ही संसाधन के लिए कई यूआरआई हो सकते हैं - कोई नियम नहीं हैं जो कहते हैं कि आपको ऐसा नहीं करना चाहिए।

और आम तौर पर, आपको वस्तुओं को सीधे या किसी अन्य चीज़ के सबसेट के रूप में एक्सेस करने की आवश्यकता हो सकती है - इसलिए आपकी संरचना मेरे लिए समझ में आती है।

सिर्फ इसलिए कि कर्मचारी विभाग के अधीन पहुंच रहे हैं:

company/{companyid}/department/{departmentid}/employees

इसका मतलब यह नहीं है कि वे कंपनी के तहत भी सुलभ नहीं हो सकते हैं:

company/{companyid}/employees

जो कर्मचारियों को उस कंपनी के लिए लौटाएगा। यह इस बात पर निर्भर करता है कि आपके उपभोग करने वाले ग्राहक की क्या आवश्यकता है - यही वह चीज है जिसके लिए आपको डिजाइन करना चाहिए।

लेकिन मुझे उम्मीद है कि सभी URL हैंडलर अनुरोधों को पूरा करने के लिए एक ही बैकिंग कोड का उपयोग करते हैं ताकि आप कोड को डुप्लिकेट नहीं कर रहे हैं।


11
यह Restful की भावना को इंगित कर रहा है, कोई नियम नहीं हैं जो कहते हैं कि आपको केवल एक सार्थक संसाधन पर विचार करना चाहिए या नहीं करना चाहिए । लेकिन आगे, मुझे आश्चर्य है कि ऐसे परिदृश्यों में कोड की नकल नहीं करने के लिए सबसे अच्छा अभ्यास क्या है।
abookyun

13
@abookyun यदि आपको दोनों मार्गों की आवश्यकता है, तो उनके बीच दोहराया नियंत्रक कोड सेवा वस्तुओं के लिए सार हो सकता है।
bgcode

इससे REST का कोई लेना-देना नहीं है। REST को इस बात की कोई परवाह नहीं है कि आप अपने URL के पथ भाग को कैसे
बनाते हैं

इस जवाब पर ड्राइविंग करते हुए, मुझे लगता है कि कोई भी एपीआई जहां डायनेमिक सेगमेंट सभी अद्वितीय पहचानकर्ता हैं, उन्हें कई डायनेमिक सेगमेंट ( /company/3/department/2/employees/1) को संभालने की आवश्यकता नहीं होनी चाहिए । यदि एपीआई प्रत्येक संसाधन प्राप्त करने के तरीके प्रदान करता है, तो उनमें से प्रत्येक अनुरोध को क्लाइंट साइड लाइब्रेरी में या कोड को पुन: उपयोग करने वाले एक-बंद समापन बिंदु के रूप में किया जा सकता है।
अधिकतम

1
जबकि कोई निषेध नहीं है, मैं इसे केवल एक संसाधन के लिए एक रास्ता होने के लिए अधिक सुरुचिपूर्ण मानता हूं - सभी मानसिक मॉडल को सरल रखता है। मैं यह भी पसंद करता हूं कि यदि कोई घोंसला हो तो यूआरआई अपने संसाधन प्रकार को नहीं बदलते हैं। उदाहरण के लिए, /company/*केवल कंपनी संसाधन वापस करना चाहिए और संसाधन प्रकार बिल्कुल नहीं बदलना चाहिए। यह कोई भी REST द्वारा निर्दिष्ट नहीं किया गया है - इसका आमतौर पर एक खराब निर्दिष्ट - सिर्फ व्यक्तिगत प्राथमिकता।
काशिफ

174

मैंने दोनों डिज़ाइन रणनीतियों की कोशिश की है - नेस्टेड और नॉन-नेस्टेड एंडपॉइंट। मैंने पाया है कि:

  1. यदि नेस्टेड संसाधन में एक प्राथमिक कुंजी है और आपके पास इसकी मूल प्राथमिक कुंजी नहीं है, तो नेस्टेड संरचना को आपको इसे प्राप्त करने की आवश्यकता है, भले ही सिस्टम को वास्तव में इसकी आवश्यकता न हो।

  2. नेस्टेड एंडपॉइंट को आम तौर पर बेमानी एंडपॉइंट की आवश्यकता होती है। दूसरे शब्दों में, आपको अधिक बार नहीं, अतिरिक्त / कर्मचारियों के समापन बिंदु की आवश्यकता होगी ताकि आप विभागों में कर्मचारियों की सूची प्राप्त कर सकें। यदि आपके पास / कर्मचारी हैं, तो क्या वास्तव में / कंपनियां / विभाग / कर्मचारी आपको खरीदते हैं?

  3. घोंसले के शिकार समापन बिंदु के रूप में अच्छी तरह से विकसित नहीं है। उदाहरण के लिए, आपको अब कर्मचारियों की खोज करने की आवश्यकता नहीं हो सकती है, लेकिन बाद में हो सकता है और यदि आपके पास एक नेस्टेड संरचना है, तो आपके पास कोई अंतिम बिंदु जोड़ने के अलावा कोई विकल्प नहीं है। गैर-नेस्टेड डिज़ाइन के साथ, आप बस अधिक पैरामीटर जोड़ते हैं, जो सरल है।

  4. कभी-कभी एक संसाधन में कई प्रकार के माता-पिता हो सकते हैं। कई एंडपॉइंट्स के परिणामस्वरूप सभी समान संसाधन लौटाते हैं।

  5. निरर्थक समापन बिंदु डॉक्स को लिखने के लिए कठिन बनाते हैं और साथ ही एपी को सीखने के लिए कठिन बनाते हैं।

संक्षेप में, गैर-नेस्टेड डिज़ाइन अधिक लचीला और सरल समापन बिंदु स्कीमा की अनुमति देता है।


24
इस उत्तर में आने के लिए बहुत ताज़ा था। मुझे पढ़ाया जा रहा है कि "सही तरीका" था के बाद अब कई महीनों से नेस्टेड समापन बिंदुओं का उपयोग कर रहा हूं। मैं आपके द्वारा ऊपर सूचीबद्ध सभी निष्कर्षों पर आया था। नॉन-नेस्टेड डिज़ाइन के साथ इतना आसान।
user3344977

6
आप अपसाइड के कुछ डाउनसाइड को सूची के रूप में सूचीबद्ध करते हैं। "बस एक ही एंड-पॉइंट में अधिक पैरामीटर रटना" एपीआई को दस्तावेज़ और सीखने के लिए कठिन बनाता है, न कि दूसरे तरीके से। ;-)
ड्रेनमी

4
इस जवाब का प्रशंसक नहीं। केवल इसलिए कि आपने एक नेस्टेड संसाधन जोड़ा है, निरर्थक समापन बिंदुओं को पेश करने की कोई आवश्यकता नहीं है। यह एक समस्या नहीं है कि एक ही संसाधन को कई माता-पिता द्वारा वापस लौटाया जाए, बशर्ते कि उन माता-पिता वास्तव में नेस्टेड संसाधन के मालिक हों। नेस्टेड संसाधनों के साथ बातचीत करने का तरीका सीखने के लिए एक मूल संसाधन प्राप्त करना कोई समस्या नहीं है। एक अच्छा खोज योग्य REST API को यह करना चाहिए।
स्कॉट डेम

3
@Scottm - मेरे पास आया नेस्टेड संसाधनों का एक दोष यह है कि यह गलत डेटा को लौटाने की ओर ले जा सकता है अगर मूल संसाधन आईडी गलत / बेमेल हैं। यह मानते हुए कि कोई प्राधिकरण मुद्दे नहीं हैं, यह सत्यापित करने के लिए कि यह वास्तव में मूल संसाधन का एक बच्चा है जिसे पारित किया गया है, यह अपी कार्यान्वयन पर छोड़ दिया गया है। यदि इस चेक को कोड नहीं किया गया है, तो एपीआई प्रतिक्रिया भ्रष्टाचार के लिए गलत हो सकती है। आपके क्या विचार हैं?
एंडी डफ्रेसने

1
अंत संसाधनों सभी अद्वितीय आईडी है, तो आप मध्यवर्ती माता पिता आईडी की जरूरत नहीं है। जैसे, आपके पास GET / कंपनियाँ / विभाग / कर्मचारी / {empId} आईडी से कर्मचारी प्राप्त करने के लिए या कंपनी 123 में सभी कर्मचारियों को पाने के लिए आपके पास GET / कंपनियाँ / 123 / विभाग / कर्मचारी / पथ को रखना पदानुक्रमित है यह अधिक स्पष्ट करता है कि कैसे आप मध्यवर्ती संसाधनों को फ़िल्टर / बनाने / संशोधित करने और मेरी राय में खोज करने में मदद कर सकते हैं।
पॉलजी

77

मैंने उस प्रश्न से उत्तर की ओर कदम बढ़ा दिया है जहाँ अधिक लोगों को इसे देखने की संभावना है।

मैंने जो किया है वह नेस्टेड एंडपॉइंट पर निर्माण समापन बिंदु है, किसी आइटम को संशोधित या क्वेरी करने के लिए विहित एंडपॉइंट नेस्टेड संसाधन पर नहीं है

तो इस उदाहरण में (सिर्फ संसाधन बदलने वाले समापन बिंदुओं को सूचीबद्ध करना)

  • POST /companies/ एक नई कंपनी बनाई गई कंपनी के लिए एक लिंक देता है।
  • POST /companies/{companyId}/departments जब कोई विभाग डाला जाता है तो नया विभाग एक लिंक देता है /departments/{departmentId}
  • PUT /departments/{departmentId} एक विभाग को संशोधित करता है
  • POST /departments/{deparmentId}/employees एक नया कर्मचारी एक लिंक देता है /employees/{employeeId}

इसलिए प्रत्येक संग्रह के लिए रूट स्तर के संसाधन हैं। हालांकि बनाने में है मालिक वस्तु।


4
मैं एक ही प्रकार के डिजाइन के साथ आया हूं। मुझे लगता है कि यह "जहां वे हैं" जैसी चीजों को बनाने के लिए सहज है, लेकिन फिर भी उन्हें विश्व स्तर पर सूचीबद्ध करने में सक्षम है। इससे भी अधिक जब एक संबंध होता है जहां एक संसाधन का एक अभिभावक होना चाहिए। फिर वैश्विक स्तर पर उस संसाधन का निर्माण करना स्पष्ट नहीं है, लेकिन इस तरह से उप-संसाधन में करना सही अर्थ है।
जोकीम

मुझे लगता है कि आपने POSTअर्थ का उपयोग किया PUT, और अन्यथा।
गेरार्डो लीमा

वास्तव में कोई नोट नहीं है कि मैं निर्माण के लिए पूर्व नियत आईडीएस का उपयोग नहीं कर रहा हूं क्योंकि इस मामले में सर्वर आईडी (लिंक में) वापस करने के लिए जिम्मेदार है। इसलिए POST लिखना सही है (एक ही कार्यान्वयन पर एक कर नहीं सकते)। हालाँकि पुट पूरे संसाधन को बदल देता है, लेकिन यह अभी भी उसी स्थान पर उपलब्ध है, इसलिए मैं इसे डालता हूं। PUT बनाम POST एक अलग मामला है और विवादास्पद भी है। उदाहरण के लिए stackoverflow.com/questions/630453/put-vs-post-in-rest
Wes

@ यहां तक ​​कि मैं माता-पिता के अधीन होने के लिए क्रिया विधियों को संशोधित करना पसंद करता हूं। लेकिन, क्या आप देखते हैं कि वैश्विक संसाधन के लिए क्वेरी पैरामीटर को अच्छी तरह से स्वीकार किया जाता है? Ex: POST / विभागों के साथ क्वेरी पैरामीटर कंपनी = company-id
अय्यप्पा

1
@ मोहम्मद अगर आपको लगता है कि दूसरा तरीका समझने में आसान है और अड़चनें लागू करने में तो आप बेझिझक जवाब दे सकते हैं। इस मामले में मानचित्रण को स्पष्ट करने के बारे में। यह एक पैरामीटर के साथ काम कर सकता है लेकिन वास्तव में यही सवाल है। सबसे अच्छा तरीका क्या है।
वेस

35

मैंने उपरोक्त सभी उत्तर पढ़े हैं, लेकिन ऐसा लगता है कि उनकी कोई सामान्य रणनीति नहीं है। मुझे Microsoft दस्तावेज़ों से डिज़ाइन एपीआई में सर्वोत्तम प्रथाओं के बारे में एक अच्छा लेख मिला । मुझे लगता है कि आपको उल्लेख करना चाहिए।

अधिक जटिल प्रणालियों में, यह यूआरआई प्रदान करने के लिए लुभाने वाला हो सकता है जो क्लाइंट को रिश्तों के कई स्तरों के माध्यम से नेविगेट करने में सक्षम बनाता है, जैसे कि /customers/1/orders/99/products., हालांकि, जटिलता का यह स्तर बनाए रखना मुश्किल हो सकता है और अनम्य हो सकता है यदि भविष्य में संसाधनों के बीच संबंध बदलते हैं। इसके बजाय, URI को अपेक्षाकृत सरल रखने का प्रयास करें । एक बार किसी एप्लिकेशन के पास एक संसाधन का संदर्भ होता है, उस संसाधन से संबंधित वस्तुओं को खोजने के लिए इस संदर्भ का उपयोग करना संभव होना चाहिए। पूर्ववर्ती क्वेरी को /customers/1/ordersग्राहक 1 के सभी आदेशों को खोजने के लिए URI के साथ बदला जा सकता है , और फिर /orders/99/productsइस क्रम में उत्पादों को खोजने के लिए।

टिप

संसाधन URI की आवश्यकता से अधिक जटिल होने से बचें collection/item/collection


3
आपके द्वारा दिया गया संदर्भ उस बिंदु के साथ-साथ अद्भुत है जो आप जटिल यूआरआई नहीं बनाने से खड़े हैं।
विस्को

इसलिए जब मैं किसी उपयोगकर्ता के लिए एक टीम बनाना चाहता हूं, तो क्या यह POST / टीमों (userId inbody) या POST / उपयोगकर्ताओं /: id / टीमों में होना चाहिए
coinhndp

@coinhndp हाय, आपको POST / टीमों का उपयोग करना चाहिए और टोकन एक्सेस को अधिकृत करने के बाद आप userId प्राप्त कर सकते हैं। मेरा मतलब है कि जब आप एक सामान बनाते हैं तो आपको प्राधिकरण कोड की आवश्यकता होती है, है ना? मुझे नहीं पता कि आप किस फ्रेमवर्क का उपयोग कर रहे हैं, लेकिन मुझे यकीन है कि आप एपीआई नियंत्रक में उपयोगकर्ता आईडी प्राप्त कर सकते हैं। उदाहरण के लिए: ASP.NET API में, ApiController पर एक विधि के भीतर RequestContext.Principal को कॉल करें। स्प्रिंग सिक्यूरिटी में, SecurityContextHolder.getContext ()। GetAuthentication ()। GetPrincipal () आपकी मदद करेगा। AWS NodeJS लैंबडा में, यह संज्ञानात्मक है: हेडर ऑब्जेक्ट में उपयोगकर्ता नाम।
लॉन्ग गुयेन

तो POST / उपयोगकर्ताओं / आईडी / टीमों के साथ क्या गलत है। मुझे लगता है कि यह Microsoft दस्तावेज़ में अनुशंसित है जिसे आपने ऊपर पोस्ट किया है
coinhndp

@coinhndp यदि आप टीम को एडमिन बनाते हैं, तो यह अच्छा है। लेकिन, सामान्य उपयोगकर्ताओं के रूप में, मुझे नहीं पता कि आपको पथ में userId की आवश्यकता क्यों है? मुझे लगता है कि हमारे पास user_A और user_B है, आपको क्या लगता है अगर user_A user_B के लिए एक नई टीम बना सकता है अगर user_A POST / users / user_B / टीमों को कॉल करता है। तो, इस मामले में userId पास करने की कोई आवश्यकता नहीं है, userId प्राधिकरण के बाद मिल सकता है। लेकिन, टीमों /: आईडी / परियोजनाओं उदाहरण के लिए टीम और परियोजना के बीच एक संबंध बनाने के लिए अच्छा है।
लॉन्ग

10

आपके URL कैसे दिखते हैं, इससे REST का कोई लेना-देना नहीं है। कुछ भी हो जाता। यह वास्तव में एक "कार्यान्वयन विवरण" है। तो जैसे आप अपने चर का नाम कैसे लेते हैं। उन्हें केवल अद्वितीय और टिकाऊ होना है।

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

ऐसा क्यों ? जहाँ तक मुझे पता है कि एक "रेस्टफुल" एपीआई को ब्राउज़ करने योग्य होना चाहिए (आप जानते हैं ... "हाइपरमेडिया ऑफ़ द इंजन ऑफ़ स्टेट"), इसलिए एक एपीआई क्लाइंट को इस बात की परवाह नहीं है कि आपके URL जितने लंबे हैं उतने लंबे मान्य (कोई SEO नहीं है, कोई भी मानव जिसे "दोस्ताना यूआरएल" पढ़ने की ज़रूरत नहीं है, सिवाय डीबगिंग के ...)

REST API में URL कितना अच्छा / समझ में आता है, यह आपके लिए केवल API डेवलपर के रूप में दिलचस्प है, API क्लाइंट के रूप में नहीं, जैसा कि आपके कोड में एक चर का नाम होगा।

सबसे महत्वपूर्ण बात यह है कि आपका एपीआई क्लाइंट आपके मीडिया प्रकार की व्याख्या करना जानता है। उदाहरण के लिए यह जानता है कि:

  • आपके मीडिया प्रकार में एक लिंक प्रॉपर्टी है जो उपलब्ध / संबंधित लिंक को सूचीबद्ध करती है।
  • प्रत्येक लिंक को एक संबंध द्वारा पहचाना जाता है (जैसे ब्राउज़र जानते हैं कि लिंक [rel = "स्टाइलशीट"] का अर्थ है इसकी स्टाइल शीट या rel = favico एक favicon के लिए एक लिंक है ...)
  • और यह पता है कि उन रिश्तों का क्या मतलब है ("कंपनियों" का मतलब कंपनियों की सूची है, "खोज" का अर्थ है संसाधन की सूची पर खोज करने के लिए एक टेम्पर्ड यूरल, "विभागों" का अर्थ है वर्तमान संसाधन के विभाग)

नीचे एक उदाहरण है HTTP एक्सचेंज (निकाय याम्ल में हैं क्योंकि यह लिखना आसान है):

निवेदन

GET / HTTP/1.1
Host: api.acme.io
Accept: text/yaml, text/acme-mediatype+yaml

प्रतिक्रिया: मुख्य संसाधन (कंपनियों, लोगों, जो भी ...) के लिंक की एक सूची

HTTP/1.1 200 OK
Date: Tue, 05 Apr 2016 15:04:00 GMT
Last-Modified: Tue, 05 Apr 2016 00:00:00 GMT
Content-Type: text/acme-mediatype+yaml

# body: this is your API's entrypoint (like a homepage)  
links:
  # could be some random path https://api.acme.local/modskmklmkdsml
  # the only thing the API client cares about is the key (or rel) "companies"
  companies: https://api.acme.local/companies
  people: https://api.acme.local/people

अनुरोध: कंपनियों से लिंक

GET /companies HTTP/1.1
Host: api.acme.local
Accept: text/yaml, text/acme-mediatype+yaml

प्रतिक्रिया: कंपनियों की एक आंशिक सूची (आइटम के तहत), संसाधन में संबंधित लिंक होते हैं, जैसे कि कंपनियों के अगले जोड़े को प्राप्त करने के लिए लिंक (body.links.next) खोज (body.links.search) के लिए एक अन्य (टेम्पर्ड) लिंक

HTTP/1.1 200 OK
Date: Tue, 05 Apr 2016 15:06:00 GMT
Last-Modified: Tue, 05 Apr 2016 00:00:00 GMT
Content-Type: text/acme-mediatype+yaml

# body: representation of a list of companies
links:
  # link to the next page
  next: https://api.acme.local/companies?page=2
  # templated link for search
  search: https://api.acme.local/companies?query={query} 
# you could provide available actions related to this resource
actions:
  add:
    href: https://api.acme.local/companies
    method: POST
items:
  - name: company1
    links:
      self: https://api.acme.local/companies/8er13eo
      # and here is the link to departments
      # again the client only cares about the key department
      department: https://api.acme.local/companies/8er13eo/departments
  - name: company2
    links:
      self: https://api.acme.local/companies/9r13d4l
      # or could be in some other location ! 
      department: https://api2.acme.local/departments?company=8er13eo

इसलिए जैसा कि आप देखते हैं कि यदि आप लिंक / संबंध बनाते हैं, तो आप अपने URL के पथ भाग की संरचना कैसे करते हैं, इसका आपके API क्लाइंट के लिए कोई मूल्य नहीं है। और यदि आप अपने ग्राहक को अपने URL की संरचना को दस्तावेज़ीकरण के रूप में बता रहे हैं, तो आप REST (या कम से कम 3 स्तर " रिचर्डसन की परिपक्वता मॉडल " के अनुसार नहीं कर रहे हैं )


7
"REST API में URL कितना अच्छा / समझ में आता है, यह केवल API डेवलपर के रूप में आपके लिए दिलचस्प है, API क्लाइंट के रूप में नहीं, जैसा कि आपके कोड में एक चर का नाम होगा।" यह दिलचस्प क्यों नहीं होगा? यह बहुत महत्वपूर्ण है, अगर कोई है लेकिन खुद भी एपीआई का उपयोग कर रहा है। यह उपयोगकर्ता अनुभव का हिस्सा है, इसलिए मैं कहूंगा कि यह बहुत महत्वपूर्ण है कि यह एपीआई क्लाइंट डेवलपर्स के लिए समझना आसान है। संसाधनों को जोड़कर चीजों को समझने में और भी आसान बनाना स्पष्ट रूप से एक बोनस है (आपके द्वारा प्रदत्त यूआरएल में स्तर 3)। स्पष्ट संबंधों के साथ सब कुछ सहज और तार्किक होना चाहिए।
जोकीम

1
@ जोकिम यदि आप एक लेवल 3 रेस्ट एपीआई (एप्लिकेशन स्टेट का हाइपरटेक्स्ट इंजन के रूप में) बना रहे हैं, तो url की पथ संरचना क्लाइंट के लिए बिल्कुल भी रूचि वाली नहीं है (जब तक यह वैध है)। यदि आप स्तर 3 के लिए लक्ष्य नहीं कर रहे हैं, तो हाँ, यह महत्वपूर्ण है और अनुमान लगाने योग्य होना चाहिए। लेकिन असली REST स्तर 3 है। एक अच्छा लेख: martinfowler.com/articles/richardsonMaturityModel.html
redben

4
मुझे कभी भी ऐसा एपीआई या यूआई बनाने पर आपत्ति है जो मानव के लिए उपयोगकर्ता के अनुकूल न हो। स्तर 3 या नहीं, मैं मानता हूं कि संसाधनों को जोड़ना एक महान विचार है। लेकिन ऐसा करने का सुझाव देने के लिए "URL योजना को बदलना संभव बनाता है" वास्तविकता के संपर्क से बाहर होना है, और लोग एपीआई का उपयोग कैसे करते हैं। तो यह एक खराब सिफारिश है। लेकिन यकीन है कि सभी दुनिया के सर्वश्रेष्ठ में हर कोई स्तर 3 बाकी पर होगा। मैं हाइपरलिंक्स को शामिल करता हूं और एक मानवीय समझ वाले URL योजना का उपयोग करता हूं। लेवल 3 में पूर्व को शामिल नहीं किया गया है, और मेरी राय में एक SHOULD की देखभाल की जाएगी। अच्छा लेख हालांकि :)
जोकिम

निश्चित रूप से रखरखाव और अन्य चिंताओं के लिए, मुझे लगता है कि आपको मेरे जवाब की बात याद आती है: जिस तरह से url दिखता है वह बहुत सोचने लायक नहीं है और आपको "बस एक विकल्प बनाना चाहिए और उसके साथ रहना चाहिए / होना चाहिए" सुसंगत ”जैसा कि मैंने उत्तर में कहा है। और REST API के मामले में, कम से कम मेरी राय, उपयोगकर्ता के
अनुकूलता

9

मैं इस तरह के रास्ते से असहमत हूं

GET /companies/{companyId}/departments

यदि आप विभागों को प्राप्त करना चाहते हैं, तो मुझे लगता है कि / a विभागों के संसाधन का उपयोग करना बेहतर है

GET /departments?companyId=123

मुझे लगता है कि आपके पास एक companiesटेबल और एक departmentsटेबल है तो कक्षाओं का उपयोग प्रोग्रामिंग भाषा में उन्हें मैप करने के लिए करें। मेरा यह भी मानना ​​है कि विभागों को कंपनियों की तुलना में अन्य संस्थाओं से जोड़ा जा सकता है, इसलिए एक / विभागों का संसाधन सीधा है, यह तालिकाओं के लिए मैप किए गए संसाधनों के लिए सुविधाजनक है और साथ ही आपको कई समापन बिंदुओं की आवश्यकता नहीं है क्योंकि आप पुन: उपयोग कर सकते हैं

GET /departments?companyId=123

किसी भी तरह की खोज के लिए, उदाहरण के लिए

GET /departments?name=xxx
GET /departments?companyId=123&name=xxx
etc.

यदि आप एक विभाग बनाना चाहते हैं, तो

POST /departments

संसाधन का उपयोग किया जाना चाहिए और अनुरोध निकाय में कंपनी आईडी होना चाहिए (यदि विभाग को केवल एक कंपनी से जोड़ा जा सकता है)।


1
मेरे लिए, यह केवल एक स्वीकार्य दृष्टिकोण है यदि नेस्टेड ऑब्जेक्ट परमाणु वस्तु के रूप में समझ में आता है। यदि वे नहीं हैं, तो यह वास्तव में उन्हें अलग करने के लिए समझ में नहीं आएगा।
सिम्मे

यही मैंने कहा है, यदि आप भी विभागों को पुनः प्राप्त करने में सक्षम होना चाहते हैं, जिसका अर्थ है कि यदि आप / विभागों के समापन बिंदु का उपयोग करेंगे।
मैक्सिमे लवल

2
किसी कंपनी को लाते समय आलसी लोडिंग के माध्यम से विभागों को शामिल करने की अनुमति देना भी समझ में आता है, उदाहरण के लिए GET /companies/{companyId}?include=departments, क्योंकि यह कंपनी और उसके विभागों दोनों को एक ही HTTP अनुरोध में लाने की अनुमति देता है। भग्न वास्तव में यह अच्छी तरह से करता है।
मैथ्यू डैली

1
जब आप एसेल्स स्थापित कर रहे हैं, तो आप शायद /departmentsएंडपॉइंट को केवल एक व्यवस्थापक द्वारा एक्सेस करने के लिए प्रतिबंधित करना चाहते हैं , और प्रत्येक कंपनी अपने स्वयं के विभागों को केवल `/ कंपनियों / {
companyId

@ मैथ्यू डीडील ओडाटा भी $ विस्तार के साथ अच्छी तरह से करता है
रोब ग्रांट

1

रेल इस के लिए एक समाधान प्रदान करता है: उथले घोंसले के शिकार

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.