URI बनाम क्वेरी स्ट्रिंग द्वारा REST एपी डिजाइन करना


73

मान लीजिए कि मेरे पास तीन संसाधन हैं जो इस तरह से संबंधित हैं:

Grandparent (collection) -> Parent (collection) -> and Child (collection)

उपरोक्त इन संसाधनों के बीच संबंध को दर्शाते हैं जैसे: प्रत्येक दादा दादी एक या कई माता-पिता के लिए मैप कर सकते हैं। प्रत्येक माता-पिता एक या कई बच्चों को मैप कर सकते हैं। मैं बाल संसाधन के विरुद्ध खोज करने की क्षमता का समर्थन करना चाहता हूं लेकिन फ़िल्टर मापदंड के साथ:

यदि मेरे ग्राहक मुझे एक दादा-दादी के लिए एक आईडी संदर्भ देते हैं, तो मैं केवल उन बच्चों के खिलाफ खोज करना चाहता हूं जो उस दादा-दादी के प्रत्यक्ष वंशज हैं।

यदि मेरे ग्राहक मुझे माता-पिता के लिए एक आईडी संदर्भ देते हैं, तो मैं केवल उन बच्चों के खिलाफ खोज करना चाहता हूं जो मेरे माता-पिता के प्रत्यक्ष वंशज हैं।

मैंने ऐसा कुछ सोचा है:

GET /myservice/api/v1/grandparents/{grandparentID}/parents/children?search={text}

तथा

GET /myservice/api/v1/parents/{parentID}/children?search={text}

उपरोक्त आवश्यकताओं के लिए, क्रमशः।

लेकिन मैं भी कुछ ऐसा कर सकता था:

GET /myservice/api/v1/children?search={text}&grandparentID={id}&parentID=${id}

इस डिजाइन में, मैं अपने क्लाइंट को एक या दूसरे को क्वेरी स्ट्रिंग में पास करने की अनुमति दे सकता था: या तो दादा-दादी या माता-पिता, लेकिन दोनों।

मेरे प्रश्न हैं:

1) कौन सा एपीआई डिजाइन अधिक प्रतिष्ठित है, और क्यों? शब्दार्थ, उनका अर्थ और व्यवहार एक जैसा है। यूआरआई में अंतिम संसाधन "बच्चे" हैं, प्रभावी रूप से यह कहते हुए कि ग्राहक बाल संसाधन पर काम कर रहा है।

2) एक ग्राहक के दृष्टिकोण से समझने की क्षमता के मामले में प्रत्येक के लिए पेशेवरों और विपक्ष क्या हैं, और डिजाइनर के दृष्टिकोण से स्थिरता है।

3) आपके संसाधन पर "फ़िल्टरिंग" के अलावा क्वेरी स्ट्रिंग्स वास्तव में किस लिए उपयोग की जाती हैं? यदि आप पहले दृष्टिकोण के साथ जाते हैं, तो फ़िल्टर पैरामीटर URI में ही क्वेरी स्ट्रिंग पैरामीटर के बजाय पथ पैरामीटर के रूप में एम्बेडेड होता है।

धन्यवाद!


3
आपके प्रश्न का शीर्षक यह देखने वाले किसी भी व्यक्ति के लिए बेहद भ्रामक होना चाहिए। एक URI के मान्य खंडों को <योजना>: // <user>: <पासवर्ड> @ <host>: <port> / <path>; <params>? <Query> / # <टुकड़ा> के रूप में परिभाषित किया गया है पासवर्ड> पदावनत है) एक "क्वेरी स्ट्रिंग" यूआरआई का एक मान्य घटक है इसलिए शीर्षक में आपका "बनाम" पागल बात है।
। एलन बेट्स

क्या आपका मतलब है I want to only search against children who are INdirect descendants of that grandparent.? आपकी संरचना के अनुसार, ग्रैंडपेरेंट के कोई प्रत्यक्ष बच्चे नहीं हैं।
नल

एक बच्चे और माता-पिता के बीच अंतर क्या है? क्या माता-पिता एक माता-पिता हैं यदि उनके बच्चे नहीं हैं? एक डिजाइन गलती की बदबू आ रही है
पिनकोक

फिर से: potential design flawऔर अगर आपको किसी व्यक्ति के बारे में जानकारी है, लेकिन उनके माता-पिता के बारे में कोई जानकारी नहीं है, तो क्या वे योग्य हैं child? (उदाहरण के लिए, एडम और ईव) :)
जेसी चिशोल्म

जवाबों:


64

प्रथम

प्रति RFC 3986 §3.4 (यूनिफ़ॉर्म रिसोर्स आइडेंटिफ़ायर Syn (सिंटैक्स कंपोनेंट्स) के अनुसार | क्वेरी |

3.4 प्रश्न

क्वेरी घटक में गैर-पदानुक्रमित डेटा होता है जो पथ घटक (धारा 3.3) में डेटा के साथ, URI की योजना और नामकरण प्राधिकरण (यदि कोई हो) के दायरे में एक संसाधन की पहचान करने का कार्य करता है।

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

REST का इस परिभाषा से कोई लेना-देना नहीं है।

आपके विशिष्ट प्रश्नों को संबोधित करने से पहले, "खोज" के आपके क्वेरी पैरामीटर का नाम खराब है। बेहतर होगा कि आप अपने क्वेरी सेगमेंट को कुंजी-मूल्य वाले जोड़े के शब्दकोश के रूप में मानें।

आपकी क्वेरी स्ट्रिंग अधिक उपयुक्त रूप से परिभाषित की जा सकती है

?first_name={firstName}&last_name={lastName}&birth_date={birthDate} आदि।

अपने विशिष्ट प्रश्नों के उत्तर देने के लिए

1) कौन सा एपीआई डिजाइन अधिक प्रतिष्ठित है, और क्यों? शब्दार्थ, उनका अर्थ और व्यवहार एक जैसा है। यूआरआई में अंतिम संसाधन "बच्चे" हैं, प्रभावी रूप से यह कहते हुए कि ग्राहक बाल संसाधन पर काम कर रहा है।

मुझे नहीं लगता कि यह उतना ही स्पष्ट है जितना आप विश्वास करते हैं।

इनमें से कोई भी संसाधन इंटरफ़ेस RESTful नहीं है। प्रमुख RESTful स्थापत्य शैली के लिए पूर्व शर्त है कि एप्लिकेशन स्थिति संक्रमण हाइपरमीडिया के रूप में सर्वर से सूचित किया जाना चाहिए है। लोगों ने यूआरआई की संरचना पर कुछ हद तक उन्हें "रेस्टफुल यूआरआई" बनाने के लिए प्रेरित किया है, लेकिन आरईएसटी के बारे में औपचारिक साहित्य वास्तव में इस बारे में कहने के लिए बहुत कम है। मेरा निजी मत है कि REST के बारे में बहुत कुछ मेटा-गलत जानकारी पुरानी, ​​बुरी आदतों को तोड़ने के इरादे से प्रकाशित की गई थी। (वास्तव में "रेस्टफुल" प्रणाली का निर्माण वास्तव में काफी काम की चीज है। उद्योग "रेस्ट" पर चमकता है और निरर्थक योग्यता और प्रतिबंधों के साथ कुछ रूढ़िवादी चिंताओं से भरा है।)

REST साहित्य क्या कहता है कि यदि आप HTTP को अपने एप्लिकेशन प्रोटोकॉल के रूप में उपयोग करने जा रहे हैं, तो आपको प्रोटोकॉल की विशिष्टताओं की औपचारिक आवश्यकताओं का पालन करना चाहिए और आप "http को बना नहीं सकते क्योंकि आप जाते हैं और फिर भी घोषणा करते हैं कि आप http का उपयोग कर रहे हैं" ; यदि आप अपने संसाधनों की पहचान करने के लिए URI का उपयोग करने जा रहे हैं, तो आपको URI / URL के बारे में विशिष्टताओं की औपचारिक आवश्यकताओं का पालन करना चाहिए।

आपका प्रश्न सीधे RFC3986 ,3.4 द्वारा संबोधित किया गया है, जिसे मैंने ऊपर जोड़ा है। इस मामले में लब्बोलुआब यह है कि भले ही एक अनुरूपित URI API "RESTful" पर विचार करने के लिए अपर्याप्त है, अगर आप चाहते हैं कि आपका सिस्टम वास्तव में "RESTful" हो और आप HTTP और URI का उपयोग कर रहे हैं, तो आप इसके माध्यम से पदानुक्रमित डेटा की पहचान नहीं कर सकते हैं क्वेरी स्ट्रिंग क्योंकि:

3.4 प्रश्न

क्वेरी घटक में गैर-पदानुक्रमित डेटा होता है

...यह उसके जैसा आसान है।

2) एक ग्राहक के दृष्टिकोण से समझने की क्षमता के मामले में प्रत्येक के लिए पेशेवरों और विपक्ष क्या हैं, और डिजाइनर के दृष्टिकोण से स्थिरता है।

पहले दो के "पेशेवरों" यह है कि वे सही रास्ते पर हैं । तीसरे का "विपक्ष" यह है कि यह गलत तरीके से सपाट प्रतीत होता है।

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

अपने शब्दार्थ यूआरआई का उनके अर्थ अर्थ में अनुवाद, /myservice/api/v1/grandparents/{grandparentID}/parents/children?search={text} यह दादा-दादी के माता-पिता के लिए कहता है, अपने बच्चे को खोजने के लिए search={text} जो आपने अपने यूआरआई के साथ कहा है वह केवल सुसंगत है अगर एक दादा-दादी के भाई-बहनों की तलाश है। अपने "दादा-दादी, माता-पिता, बच्चों" के साथ आपने पाया "एक दादा-दादी" अपने माता-पिता के लिए एक पीढ़ी से ऊपर चले गए और फिर माता-पिता के बच्चों को देखकर "दादा-दादी" की पीढ़ी में वापस आ गए।

/myservice/api/v1/parents/{parentID}/children?search={text} यह कहता है कि {पेरेंटिड} द्वारा पहचाने गए अभिभावक के लिए, उनके बच्चे को खोजें कि ?search={text}यह वही है जो आप चाहते हैं के लिए सही है, और यह माता-पिता-> बाल संबंध का प्रतिनिधित्व करता है जो संभवतः आपके संपूर्ण एपीआई को मॉडल करने के लिए उपयोग किया जा सकता है। इसे इस तरह से मॉडल करने के लिए, ग्राहक पर यह मानने के लिए कि उसे "दादा-दादी" कहा जाता है, के लिए बोझ रखा गया है, कि उनके पास मौजूद आईडी और परिवार के ग्राफ के हिस्से के बीच अप्रत्यक्ष रूप से एक परत है। "दादा-दादी" द्वारा "बच्चे" को खोजने के लिए, आप अपनी /parents/{parentID}/childrenसेवा को कॉल कर सकते हैं और फिर वापस आने वाले बच्चे की खोज कर सकते हैं, अपने बच्चों को अपने व्यक्ति पहचानकर्ता के लिए खोज सकते हैं।

यूआरआई के रूप में अपनी आवश्यकताओं का कार्यान्वयन यदि आप एक अधिक विलक्षण संसाधन पहचानकर्ता को मॉडल करना चाहते हैं जो पेड़ पर चल सकता है, तो मैं कई तरीकों के बारे में सोच सकता हूं जिन्हें आप पूरा कर सकते हैं।

1) पहले एक, मैं पहले से ही करने के लिए तैयार है। एक समग्र संरचना के रूप में "पीपल" के ग्राफ का प्रतिनिधित्व करते हैं। प्रत्येक व्यक्ति को अपने माता-पिता के पथ के माध्यम से इसके ऊपर की पीढ़ी का और इसके नीचे के बच्चों के माध्यम से एक पीढ़ी का संदर्भ है।

/Persons/Joe/Parents/Mother/Parents जो जो के दादा दादी को हथियाने का एक तरीका होगा।

/Persons/Joe/Parents/Parents जो के दादा-दादी के सभी को हथियाने का एक तरीका होगा।

/Persons/Joe/Parents/Parents?id={Joe.GrandparentID} आपके हाथ में पहचानकर्ता होने वाले जो के दादा-दादी को पकड़ लेगा।

और ये सभी समझ में आएंगे (ध्यान दें कि "माता-पिता / माता-पिता / माता-पिता / माता-पिता" पैटर्न में शाखा की पहचान की कमी के कारण सर्वर पर कार्य करने के लिए कार्य के आधार पर यहां एक प्रदर्शन जुर्माना हो सकता है।) आप भी होने से लाभ उठाते हैं। पीढ़ियों की किसी भी मनमानी संख्या का समर्थन करने की क्षमता। यदि, किसी कारण से, आप 8 पीढ़ियों को देखना चाहते हैं, तो आप इस का प्रतिनिधित्व कर सकते हैं

/Persons/Joe/Parents/Parents/Parents/Parents/Parents/Parents/Parents/Parents?id={Joe.NotableAncestor}

लेकिन यह इस डेटा का प्रतिनिधित्व करने के लिए दूसरे प्रमुख विकल्प की ओर जाता है: एक पथ पैरामीटर के माध्यम से।


2) "पदानुक्रम को क्वेरी करने के लिए" पथ मापदंडों का उपयोग करें। आप उपभोक्ताओं पर बोझ को कम करने में मदद करने के लिए निम्नलिखित संरचना विकसित कर सकते हैं और अभी भी एक एपीआई है जो समझ में आता है।

147 पीढ़ियों को देखने के लिए, पथ मापदंडों के साथ इस संसाधन पहचानकर्ता का प्रतिनिधित्व करना आपको करने की अनुमति देता है

/Persons/Joe/Parents;generations=147?id={Joe.NotableAncestor}

अपने महान दादा-दादी से जो का पता लगाने के लिए, आप ग्राफ को जे की ईद के लिए कई पीढ़ियों तक ज्ञात कर सकते हैं। /Persons/JoesGreatGrandparent/Children;generations=3?id={Joe.Id}

इन दृष्टिकोणों के साथ ध्यान देने की प्रमुख बात यह है कि पहचानकर्ता और अनुरोध में अधिक जानकारी के बिना, आपको यह उम्मीद करनी चाहिए कि पहला यूआरआई एक व्यक्ति 147 पीढ़ियों को जो से पहचान कर रहा है। आपको दूसरे को पुनः प्राप्त करने की उम्मीद करनी चाहिए। यह मान लें कि आप वास्तव में जो चाहते हैं, वह आपके कॉलिंग क्लाइंट के लिए नोड के पूरे सेट और रूट पर्सन और आपके यूआरआई के अंतिम संदर्भ के बीच उनके संबंधों को फिर से प्राप्त करने में सक्षम होना है। आप उसी URI के साथ (कुछ अतिरिक्त सजावट के साथ) कर सकते हैं और text/vnd.graphvizआपके अनुरोध पर एक एक्सेप्ट सेट कर सकते हैं, जो .dotग्राफ प्रतिनिधित्व के लिए IANA पंजीकृत मीडिया प्रकार है । इसके साथ ही, URI को बदल दें

/Persons/Joe/Parents;generations=147?id={Joe.NotableAncestor.Id}#directed

HTTP रिक्वेस्ट हैडर के साथ Accept: text/vnd.graphviz और आपके पास क्लाइंट्स का स्पष्ट रूप से संवाद हो सकता है कि वे जो और 147 पीढ़ियों के बीच जेनरल पदानुक्रम के निर्देशित ग्राफ को चाहते हैं, जहां 147 वीं पैतृक पीढ़ी में एक व्यक्ति जो जो के "उल्लेखनीय पूर्वज" के रूप में पहचाना जाता है।

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


3) आपके संसाधन पर "फ़िल्टरिंग" के अलावा क्वेरी स्ट्रिंग्स वास्तव में किस लिए उपयोग की जाती हैं? यदि आप पहले दृष्टिकोण के साथ जाते हैं, तो फ़िल्टर पैरामीटर URI में ही क्वेरी स्ट्रिंग पैरामीटर के बजाय पथ पैरामीटर के रूप में एम्बेडेड होता है।

मेरा मानना ​​है कि मैंने पहले ही इसे अच्छी तरह से मार डाला है, लेकिन क्वेरी स्ट्रिंग्स "फ़िल्टरिंग" संसाधनों के लिए नहीं हैं। वे गैर-पदानुक्रमित डेटा से आपके संसाधन की पहचान करने के लिए हैं । यदि आपने जाकर अपने पदानुक्रम को अपने रास्ते से नीचे गिरा दिया है /person/{id}/children/और आप एक विशिष्ट बच्चे या बच्चों के एक विशिष्ट समूह की पहचान करना चाहते हैं, तो आप कुछ विशेषता का उपयोग करेंगे जो उस सेट पर लागू होते हैं जिसे आप पहचान रहे हैं और इसे क्वेरी के अंदर शामिल करें।


1
RFC केवल पदानुक्रम इन्सोफ़र से संबंधित है क्योंकि यह सापेक्ष URI संदर्भों को हल करने के लिए एक वाक्यविन्यास और एल्गोरिथ्म को परिभाषित करता है। क्या आप कुछ स्रोतों का विस्तृत या हवाला देते हुए बता सकते हैं कि मूल पद के उदाहरण अनुरूप क्यों नहीं हैं?
user2313838

2
एक परिवार का पेड़ वास्तव में एक ग्राफ नहीं एक पेड़ है, और सभी श्रेणीबद्ध नहीं है। कई माता-पिता, तलाक और फिर से विवाह आदि पर विचार करना
मिस्टर

1
@RobertoAloi मुझे लगता है कि HTTP के लिए पहले से ही एक परिभाषा है, जब एक खाली सेट के माध्यम से अपने स्वयं के "नो आइटम्स फाउंड" इंटरफ़ेस को संप्रेषित करने के लिए मेरे लिए प्रतिरूपात्मक लगता है। मूल सिद्धांत यह है कि आप सर्वर को "चीज़ (ओं)" को वापस करने के लिए कह रहे हैं और यदि कोई "चीज़ (ओं)" को वापस करने के लिए नहीं हैं, तो सर्वर "404 - Not Found" के साथ संचार करता है कि इसके बारे में क्या है?
। एलन बेट्स

1
मैंने हमेशा 404 को यह संकेत दिया कि संसाधन का रूट URL नहीं मिला है, अर्थात संपूर्ण रूप से संग्रह। इसलिए यदि आपने पुस्तकों / पुस्तकों को उद्धृत किया है? लेखक = जिम और जिम द्वारा कोई किताबें नहीं थीं, तो आपको एक खाली सेट प्राप्त होगा []। लेकिन अगर आपने लेखों / लेखों को उद्धृत किया है? लेखक = जिम लेकिन लेख संसाधन 404 भी एक संग्रह के रूप में मौजूद नहीं था, यह इंगित करने में मदद करेगा कि किसी भी लेख की तलाश में इसका कोई उपयोग नहीं है।
adjenks

1
@adjenks आपने औपचारिक विनिर्देशों से यह नहीं सीखा। संरचनात्मक रूप से, एक url के घटक को "मूल" से युक्त माना जा सकता है, यदि यह आपको घटक भागों के उद्देश्यों के बारे में कारण में मदद करता है, लेकिन अंततः क्वेरी स्ट्रिंग पथ के माध्यम से पहचाने गए संसाधन के खिलाफ प्रदर्शन फ़िल्टर नहीं है। क्वेरी स्ट्रिंग एक url का प्रथम श्रेणी का नागरिक है। जब आपको सर्वर पर कोई संसाधन नहीं मिलता है जो आपके url (क्वेरी स्ट्रिंग सहित) से मेल खाता है 404 यह संचार करने के लिए http के भीतर परिभाषित साधन है। आपके द्वारा बोला गया इंटरएक्शन मॉडल बिना किसी अंतर के एक अंतर का परिचय देता है।
। एलन बेट्स

14

यह वह जगह है जहाँ आप इसे गलत करते हैं:

यदि मेरे ग्राहक मेरे लिए आईडी संदर्भ देते हैं

REST सिस्टम में, क्लाइंट को कभी भी ID से परेशान नहीं होना चाहिए। एकमात्र संसाधन पहचानकर्ता है जिसके बारे में ग्राहक को पता होना चाहिए कि उसे यूआरआई होना चाहिए। यह "वर्दी इंटरफ़ेस" का सिद्धांत है।

इस बारे में सोचें कि क्लाइंट आपके सिस्टम के साथ कैसे इंटरैक्ट करेंगे। यूं कहें कि उपयोगकर्ता दादा-दादी की सूची के माध्यम से ब्राउज़ करना शुरू कर देता है, उसने दादा-दादी के बच्चे में से एक को चुना, जो उसे लाता है /grandparent/123। यदि क्लाइंट को बच्चों के खोज करने में सक्षम होना चाहिए /grandparent/123, तो "HATEOAS" के अनुसार, जब आप क्वेरी करते हैं तो जो कुछ भी /grandparent/123खोज इंटरफ़ेस में एक URL को वापस करना चाहिए। इस URL में पहले से ही डेटा मौजूद होना चाहिए जो कि इसमें मौजूद दादा दादी द्वारा फ़िल्टर किया गया हो।

लिंक की तरह लग रहा है या नहीं /grandparent/123?search={term}या /parent?grandparent=123&search={term}या /parent?grandparentTerm=someterm&someothergplocator=blah&search={term}बाकी के अनुसार अप्रासंगिक हैं। ध्यान दें कि उन सभी URL में समान मापदंडों की संख्या है, जो है {term}, भले ही वे विभिन्न मानदंडों का उपयोग करते हों। आप उन URL में से किसी के बीच स्विच कर सकते हैं या आप विशिष्ट दादा-दादी के आधार पर उन्हें मिला सकते हैं और क्लाइंट नहीं टूटेगा, क्योंकि संसाधनों के बीच तार्किक संबंध समान होते हुए भी अंतर्निहित कार्यान्वयन में काफी भिन्नता हो सकती है।

यदि आपने इसके बजाय ऐसी सेवा बनाई है, जिसकी आवश्यकता /grandparent/{grandparentID}?search={term}तब होती है जब आप एक तरह से जाते हैं, लेकिन /children?parent={parentID}&search={term}} जब आप दूसरे तरीके से जाते हैं, तो यह बहुत अधिक युग्मन होता है क्योंकि ग्राहक को विभिन्न संबंधों पर अलग-अलग चीजों को प्रक्षेपित करने के लिए जानना होगा जो वैचारिक रूप से समान हैं।

चाहे आप वास्तव में साथ जाएं /grandparent/123?search={term}या /parent?grandparent=123&search={term}स्वाद की बात है और जो भी आपके लिए अभी लागू करना आसान है। महत्वपूर्ण बात यह है कि क्लाइंट को संशोधित करने की आवश्यकता नहीं है यदि आप अपनी यूआरएल रणनीति बदलते हैं या यदि आप विभिन्न माता-पिता-बच्चों के संबंधों पर विभिन्न रणनीतियों का उपयोग करते हैं।


10

मुझे यकीन नहीं है कि लोग आईडी मानों को URL में डालने के बारे में क्यों सोचते हैं इसका मतलब किसी भी तरह से एक REST API है, REST क्रियाओं, पासिंग संसाधनों को संभालने के बारे में है।

इसलिए यदि आप एक नए उपयोगकर्ता को PUT करना चाहते हैं, तो आपको डेटा का उचित हिस्सा भेजना होगा और एक POST http अनुरोध आदर्श है, इसलिए यदि आप कुंजी भेज सकते हैं (उदाहरण के लिए उपयोगकर्ता आईडी), तो आप उपयोगकर्ता को भेज देंगे। (उदा। नाम, पता) POST डेटा के रूप में।

अब यूआरआई में रिसोर्स आइडेंटिफ़ायर लगाना एक आम मुहावरा है, लेकिन यह "यूआरआई में नहीं तो अपने रेस्ट नहीं" के विहित किसी भी रूप से ज्यादा कन्वेंशन है। याद रखें कि REST की मूल थीसिस वास्तव में http का उल्लेख नहीं करती है, इसके क्लाइंट-सर्वर में डेटा को संभालने के लिए एक मुहावरा है, न कि ऐसा कुछ जो http (हालांकि, जाहिर है, http हमारे लिए REST लागू करने का प्राथमिक रूप है) का विस्तार है ।

उदाहरण के लिए, फील्डिंग एक उदाहरण के रूप में अकादमिक पेपर के अनुरोध का उपयोग करता है। आप "बियर पीने पर डॉ। जॉन पेपर" संसाधन को पुनः प्राप्त करना चाहते हैं, लेकिन आप प्रारंभिक संस्करण, या नवीनतम संस्करण भी चाहते हैं, इसलिए संसाधन पहचानकर्ता कुछ ऐसा नहीं हो सकता है जो आसानी से एकल आईडी के रूप में संदर्भित हो। URI में रखा गया। REST इसके लिए अनुमति देता है और इसके पीछे एक घोषित इरादा है:

REST एक संसाधन पहचानकर्ता चुनने वाले लेखक पर निर्भर करता है जो पहचाने जा रहे अवधारणा की प्रकृति को सबसे अच्छी तरह से फिट करता है

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

मुझे लगता है कि REST इंटरफ़ेस का एक उदाहरण जो आमतौर पर उल्लिखित नहीं है, वह SMTP है । मेल संदेश का निर्माण करते समय, आप मेल संदेश के प्रत्येक भाग के लिए संसाधन डेटा के साथ क्रिया (FROM, TO आदि) भेजते हैं। यह RESTful है भले ही यह http क्रिया का उपयोग नहीं करता है, यह अपने स्वयं के सेट का उपयोग करता है।

इसलिए ... जब तक आपको अपने यूआरआई में कुछ संसाधन पहचान की आवश्यकता होती है, तब तक यह आपके आईडी संदर्भ के लिए नहीं होता है। इसे ख़ुशी से नियंत्रण डेटा के रूप में, क्वेरी स्ट्रिंग या POST डेटा में भी भेजा जा सकता है। आप वास्तव में अपने REST API में जो पहचान रहे हैं वह यह है कि आप एक बच्चे के बाद हैं, जो आपके URI में पहले से मौजूद है।

इसलिए मेरे दिमाग में, REST की परिभाषा को पढ़ते हुए, आप एक बाल संसाधन से अनुरोध कर रहे हैं, जो आप वापस लौटना चाहते हैं, यह निर्धारित करने के लिए नियंत्रण डेटा (querystring के रूप में) में गुजर रहा है। परिणामस्वरूप, आप एक दादा-दादी या माता-पिता के लिए URI अनुरोध नहीं कर सकते। आप चाहते हैं कि बच्चे वापस लौटे, इसलिए माता-पिता / दादा-दादी या आईडी शब्द निश्चित रूप से ऐसे यूआरआई में नहीं होना चाहिए। बच्चे होने चाहिए।


दरअसल, URI एक अवधारणा के रूप में REST के लिए केंद्रीय है। यूआरआई सिंटैक्स के रूप में क्या महत्वपूर्ण नहीं है। एक उचित REST इंटरफ़ेस को एक सामान्य सिंटैक्स वाले संसाधनों की पहचान करनी चाहिए। REST सिद्धांत के आधार पर, RFC 3986 URI के बजाय JSON ऑब्जेक्ट के साथ जटिल संसाधन की पहचान करना आवश्यक नहीं है, हालांकि यदि आप ऐसा करते हैं, तो आपको अपने पूरे API के लिए JSON RI का उपयोग करना चाहिए।
रेयान

4

बहुत सारे लोग पहले से ही इस बारे में बात कर चुके हैं कि REST का मतलब क्या है, आदि आदि। लेकिन असली मुद्दे को संबोधित करने के लिए कोई भी नहीं लगता है: आपका डिज़ाइन।

दादा-दादी एक पिता से अलग क्यों हैं? वे दोनों बच्चे हैं कि संभवतः बच्चे हो सकते हैं ...

आखिरकार, वे सभी 'मानव' हैं। आपके पास शायद आपके कोड में भी है। तो इसका उपयोग करें:

GET /<api-endpoint>/humans/<ID>

मानव के बारे में कुछ उपयोगी जानकारी लौटाएगा। (नाम, और सामान)

GET /<api-endpoint>/humans/<ID>/children

जाहिर है कि बच्चों की एक सरणी वापस आ जाएगी। यदि कोई बच्चा मौजूद नहीं है, तो खाली सरणी शायद जाने का रास्ता है।

इसे आसान बनाने के लिए, आप उदाहरण के लिए एक ध्वज 'हैशल्ड्रेन' जोड़ सकते हैं। या 'hasGrandChildren' है।

सोचिए होशियार मुश्किल नहीं है


1

निम्नलिखित अधिक RESTfull है क्योंकि प्रत्येक दादा-दादी को इसका अपना URL मिलता है। इस तरह से संसाधन की पहचान एक अनोखे तरीके से हो जाती है।

GET /myservice/api/v1/grandparents/{grandparentID}
GET /myservice/api/v1/grandparents/{grandparentID}/parents/children?search={text}

क्वेरी पैरामीटर खोज उस संसाधन के संदर्भ से खोज निष्पादित करने का एक अच्छा तरीका है।

जब कोई परिवार बहुत बड़ा हो रहा है तो आप उदाहरण के लिए क्वेरी विकल्प के रूप में प्रारंभ / सीमा का उपयोग कर सकते हैं:

GET /myservice/api/v1/grandparents/{grandparentID}/children?start=1&limit=50

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

शायद यह एक अच्छा पढ़ा है http://www.thoughtworks.com/insights/blog/rest-ap-design-resource-modeling और अन्यथा रॉय टी फील्डिंग की मूल पीएचडी थीसिस https://www.ics.uci.edu /~fielding/pubs/dissertation/fielding_dissertation.pdf जो अवधारणाओं को बहुत अच्छी तरह से और पूरा समझाता है।


1

मैं साथ चलूँगा

/myservice/api/v1/people/{personID}/descendants/2?search={text}

इस मामले में प्रत्येक उपसर्ग एक मान्य संसाधन है:

  • /myservice/api/v1/people: सभी लोग
  • /myservice/api/v1/people/{personID}: एक व्यक्ति जिसकी पूरी जानकारी हो (पूर्वजों, भाई-बहनों, वंशजों सहित)
  • /myservice/api/v1/people/{personID}/descendants: एक व्यक्ति के वंशज
  • /myservice/api/v1/people/{personID}/descendants/2: एक व्यक्ति के पोते

सबसे अच्छा जवाब नहीं हो सकता है, लेकिन कम से कम मेरे लिए समझ में आता है।


-1

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

आपके उदाहरण में / myservice / api / v1 / grandparents / {grandparentID} / माता-पिता / बच्चे? खोज {{पाठ}

अगर आप इसे / myservice / api / v1 / siblingsOfGrandParents?

इस स्थिति में आप 'siblingsOfGrandParents' को संसाधन घोषित कर सकते हैं। यह URL को सरल करता है

जैसा कि दूसरों ने बताया कि व्यापक रूप से एक गलत धारणा है कि आपको URL में अधिक स्पष्ट रूप में डोमेन ऑब्जेक्ट के बीच हर प्रकार के पदानुक्रमित संबंध में फिट होने की आवश्यकता है..तो डोमेन ऑब्जेक्ट्स के लिए 1-to1 मैपिंग करना कोई कठिन और तेज़ नियम नहीं है और संसाधन और उनके सभी रिश्तों का प्रतिनिधित्व करते हैं ... सवाल यह होना चाहिए कि मेरा मानना ​​है ... URLs के माध्यम से इस तरह के संबंधों को उजागर करने की आवश्यकता है ... विशेष रूप से पथ खंड ... शायद नहीं।


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

मुझे पूरी तरह से यकीन नहीं है कि आपके उत्तर को पढ़ने के आधार पर क्यों डाउनवोट किया गया है। मैं आपसे सहमत हुँ। कुछ तात्कालिक चीजें जो मेरे सामने आती हैं, वह यह है कि आपने "भाई-बहनों" का उल्लेख करते हुए थोड़ा सा मूर्त उदाहरण दिया, जब ओपी पदानुक्रमित संबंधों के बारे में पूछ रहा था। शायद आपकी लेखन शैली में भी सुधार किया जा सके। आप बहुत सारे "..." का उपयोग करते हैं, हम औपचारिक, व्यावसायिक, या निर्देशात्मक लेखन में "..." का उपयोग नहीं करते हैं। वहाँ भी अतिरेक है (उदाहरण के लिए आप उल्लेख करते हैं, तो अपने उदाहरण में कहें)। शायद आपका जवाब अधिक संक्षिप्त हो सकता है और अधिक सीधे ओपी प्रश्न को संबोधित कर सकता है।
केनीकासन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.