जब मैं RESTful API में पथ परम बनाम क्वेरी परम का उपयोग करता हूं?


141

मैं अपना RESTful API बहुत प्रेडिक्टेबल बनाना चाहता हूं। क्वेरी पैरामैड का उपयोग करके URI का उपयोग करके डेटा का विभाजन करने के लिए निर्णय लेने के लिए सबसे अच्छा अभ्यास क्या है।

यह मेरे लिए समझ में आता है कि सिस्टम पैरामीटर जो पेजिंग, सॉर्टिंग और ग्रुपिंग का समर्थन करते हैं, '?' लेकिन 'स्टेटस ’और other रीजन’ जैसे क्षेत्रों या अन्य विशेषताओं के बारे में क्या जो आपके संग्रह को खंडित करते हैं? यदि उन लोगों को क्वेरी परम के रूप में अच्छी तरह से किया जा रहा है, तो यह जानने के लिए कि पथ परम का उपयोग कब करना है?


1
इसी तरह के एक सवाल का जवाब यहां दिया गया है ... stackoverflow.com/questions/3198492/…
ललित मेहरा

जवाबों:


239

रेस्टफुल एपीआई डिजाइन के लिए सबसे अच्छा अभ्यास यह है कि किसी विशेष संसाधन या संसाधनों की पहचान करने के लिए पथ पार्म्स का उपयोग किया जाता है, जबकि क्वेरी पैरामीटर का उपयोग उन संसाधनों को सॉर्ट / फ़िल्टर करने के लिए किया जाता है।

यहाँ एक उदाहरण है। मान लीजिए कि आप कार नामक इकाई के लिए RESTful API एंडपॉइंट को लागू कर रहे हैं। आप इस तरह से अपने समापन बिंदुओं की संरचना करेंगे:

प्राप्त /cars
प्राप्त /cars/:id
पोस्ट /cars
डाल /cars/:id
हटाएँ/cars/:id

इस तरह से आप केवल पथ मापदंडों का उपयोग कर रहे हैं जब आप निर्दिष्ट कर रहे हैं कि किस संसाधन को लाना है, लेकिन यह किसी भी तरह से संसाधनों को सॉर्ट / फ़िल्टर नहीं करता है।

अब मान लीजिए कि आप अपने GET अनुरोधों में कारों को फ़िल्टर करने की क्षमता जोड़ना चाहते थे। क्योंकि रंग एक संसाधन नहीं है (यह एक संसाधन की संपत्ति है), आप एक क्वेरी पैरामीटर जोड़ सकते हैं जो ऐसा करता है। आप उस क्वेरी पैरामीटर को अपने GET/cars अनुरोध में इस तरह जोड़ेंगे :

प्राप्त /cars?color=blue

यह समापन बिंदु लागू किया जाएगा ताकि केवल नीली कारों को वापस किया जाए।

जहाँ तक सिंटैक्स का संबंध है, आपके URL के नाम सभी लोअरकेस में होने चाहिए। यदि आपके पास एक इकाई का नाम है जो आम तौर पर अंग्रेजी में दो शब्द हैं, तो आप शब्दों को अलग करने के लिए एक हाइफ़न का उपयोग करेंगे, न कि ऊंट के मामले में।

पूर्व। /two-words


3
आपके उत्तर के लिए धन्यवाद माइक। यह एक स्पष्ट और सरल पद्धति है; मुझ से एक अप वोट के लायक। फिर भी, अक्सर, डेवलपर्स 'कारों / नीले' दृष्टिकोण के लिए चुनते हैं, मैं सोच रहा हूं कि ऐसा करने के लिए उनका तर्क क्या है ... शायद वे उन क्षेत्रों के लिए पथ पारम बनाने का फैसला करते हैं जो अनिवार्य हैं, या शायद वे ऐसा करने के लिए संकेत देते हैं डेटाबेस उस शार्क द्वारा विभाजित किया गया है।
cosbor11

1
मुझे यकीन नहीं है कि उनका तर्क क्या है। ईमानदारी से कहूं तो मैं इससे असहमत हूं। मुझे लगता है कि परंपराओं का पालन करना और इसे सरल बनाए रखना सबसे ज्यादा मायने रखता है। ऐसा करने से, आप अपने API के उपभोक्ताओं को बेहतर तरीके से समझने की अनुमति देते हैं कि उन्हें इसकी कार्यक्षमता तक पहुंचने के लिए क्या करना है।
माइक

3
क्या कारों / कारों के बारे में? आईडी = 1 और रंग = कारों के बजाय नीला / 1? रंग = नीला। आप मूल रूप से प्रत्येक परिदृश्य में कारों के संसाधनों को छान रहे हैं
एमके

1
आईडी 1 के साथ कार के बाद से गलत केवल एक ही मौजूद है, लेकिन रंग के साथ कारें शायद कई। पहचान और फिल्टर के बीच अंतर है
पॉल

1
पथ परम का उपयोग करने के बारे में मेरी परिकल्पना इतनी व्यापक है क्योंकि कई डेवलपर्स ऐसे लोगों द्वारा डिज़ाइन किए गए फ्रेमवर्क से सीखते हैं जिनके पास REST सिद्धांतों (विशेष रूप से रेल पर रूबी) का अच्छा पकड़ नहीं है।
क्रिस ब्रॉस्की

58

इस विषय पर सोचने का मूल तरीका इस प्रकार है:

एक यूआरआई एक संसाधन पहचानकर्ता है जो विशिष्ट रूप से संसाधन TYPE के विशिष्ट उदाहरण की पहचान करता है। जीवन में हर चीज की तरह, हर वस्तु (जो किसी प्रकार का एक उदाहरण है) में ऐसे गुण होते हैं जो या तो समय-अपरिवर्तनीय या अस्थायी होते हैं।

ऊपर के उदाहरण में, एक कार एक बहुत ही ठोस वस्तु है जिसमें मेक, मॉडल और VIN जैसे गुण हैं - जो कभी नहीं बदलते हैं, और रंग, निलंबन आदि जो समय के साथ बदल सकते हैं। इसलिए यदि हम समय के साथ (अस्थायी) बदल सकने वाली विशेषताओं के साथ यूआरआई को एनकोड करते हैं, तो हम एक ही वस्तु के लिए कई यूआरआई के साथ समाप्त हो सकते हैं:

GET /cars/honda/civic/coupe/{vin}/{color=red}

और वर्षों बाद, यदि इसी कार का रंग बदलकर काला कर दिया जाए:

GET /cars/honda/civic/coupe/{vin}/{color=black}

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

इसलिए, यूआरआई में केवल ऐसे हिस्से शामिल होने चाहिए जो कभी नहीं बदलेंगे और जीवन भर उस संसाधन की विशिष्ट पहचान करते रहेंगे। सब कुछ जो बदल सकता है, क्वेरी पैरामीटर के लिए आरक्षित होना चाहिए, जैसे:

GET /cars/honda/civic/coupe/{vin}?color={black}

निचला रेखा - बहुरूपता पर विचार करें।


2
दिलचस्प प्रतिमान .. क्या यह आमतौर पर इस्तेमाल किया जाने वाला डिज़ाइन है? क्या आप कुछ एपीआई प्रदान कर सकते हैं जो उनके प्रलेखन में उपयोग करते हैं या कुछ संदर्भ जो इस रणनीति को रेखांकित करते हैं?
cosbor11

1
मुझे पसंद है कि आपने "TYPE" पर कैसे जोर दिया था जब आपने लिखा था "A URI एक संसाधन पहचानकर्ता है जो विशिष्ट रूप से एक संसाधन TYPE के विशिष्ट उदाहरण की पहचान करता है"। मुझे लगता है कि यह एक महत्वपूर्ण अंतर है।
जारहाली

15

REST API में, आपको पूर्वानुमानित URI के द्वारा अत्यधिक चिंतित नहीं होना चाहिए। URI प्रेडिक्टिबिलिटी का बहुत सुझाव Restful आर्किटेक्चर की गलतफहमी को दूर करता है। यह मानता है कि एक ग्राहक को स्वयं URI का निर्माण करना चाहिए, जो उन्हें वास्तव में नहीं करना चाहिए।

हालाँकि, मुझे लगता है कि आप एक वास्तविक REST API नहीं बना रहे हैं, लेकिन 'REST प्रेरित' API (जैसे Google ड्राइव एक)। इन मामलों में अंगूठे का नियम 'पथ परमस = संसाधन पहचान' और 'क्वेरी परम = संसाधन छँटाई' है। तो, सवाल यह है कि क्या आप विशिष्ट रूप से स्थिति / क्षेत्र के बिना अपने संसाधन की पहचान कर सकते हैं? यदि हाँ, तो शायद यह एक क्वेरी परम है। यदि नहीं, तो इसका एक पथ परम है।

HTH।


11
मैं असहमत हूं, एक अच्छा एपीआई पूर्वानुमान योग्य होना चाहिए; उद्दंड या अन्यथा।
cosbor11

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

2
"जब कोई दस्तावेज़ को संदर्भित किए बिना लगातार एपीआई क्लाइंट लिख सकता है"। यहीं पर मुझे लगता है कि REST की हमारी समझ अलग है ... API क्लाइंट को कभी भी URL बनाने की आवश्यकता नहीं होनी चाहिए। उन्हें पिछले एपीआई कॉल की प्रतिक्रिया से इसका चयन करना चाहिए। यदि आप एक वेबसाइट को एक सादृश्य के रूप में लेते हैं ... आप facebook.com पर जाते हैं, तो आप ईवेंट पृष्ठ के लिंक का चयन करते हैं। आपको परवाह नहीं है कि क्या फेसबुक ईवेंट URL 'प्रेडिक्टेबल' है, जैसा कि आप इसे टाइप करने में सक्षम हैं। आप हाइपरमीडिया लिंक के माध्यम से वहां पहुंचते हैं। यही हाल रीस्ट एपीआई का है। तो, आप (सर्वर) के लिए URI को सार्थक बनाएं, लेकिन ग्राहक नहीं
ओलिवर McPhee

2
जोड़ा गया नोट। इसका मतलब यह नहीं है कि URI को पैटर्न को समझने में आसान का पालन नहीं करना चाहिए, इसका मतलब यह है कि यह एक RESTful API का अवरोध नहीं है। इस क्षेत्र के साथ सबसे बड़ा मुद्दा यह है कि लोग यह मान रहे हैं कि एक ग्राहक को स्वयं URL का निर्माण करना चाहिए। वे नहीं होना चाहिए, क्योंकि यह ग्राहक और सर्वर के बीच एक युग्मन बनाता है जो मौजूद नहीं होना चाहिए। (जैसे - सर्वर तब सभी क्लाइंट एप्लिकेशन को तोड़े बिना URL नहीं बदल सकता है)। REST API में, सर्वर उन्हें बदल सकता है जैसा कि वह चाहता है।
ओलिवर मैकफी ने

3
निम्नलिखित शब्दों का उपयोग करने के लिए +1: "पथ परमेस = संसाधन पहचान" और 'क्वेरी परम = संसाधन सॉर्टिंग "। यह वास्तव में यह मेरे लिए मंजूरी दे दी।
डग

3

एक बार मैंने एक एपीआई डिजाइन किया जो मुख्य संसाधन था people। आमतौर पर उपयोगकर्ता फ़िल्टर किए जाने का अनुरोध करते हैंpeople करने का करते हैं, ताकि उपयोगकर्ताओं को /people?settlement=urbanहर बार कुछ कॉल करने से रोकने के लिए , मैंने इसे लागू /people/urbanकिया , जिसने बाद में मुझे आसानी से जोड़ने में सक्षम किया /people/rural। इसके अलावा यह पूरी /peopleसूची तक पहुँचने की अनुमति देता है अगर यह बाद में किसी काम का होगा। संक्षेप में, मेरा तर्क सामान्य सबसेट के लिए एक रास्ता जोड़ना था

से यहाँ :

सामान्य प्रश्नों के लिए उपनाम

औसत उपभोक्ता के लिए एपीआई के अनुभव को और अधिक सुखद बनाने के लिए, शर्तों के सेट को आसानी से सुलभ Restful पथों में पैकेजिंग पर विचार करें। उदाहरण के लिए, ऊपर हाल ही में बंद टिकट क्वेरी को ऊपर पैक किया जा सकता हैGET /tickets/recently_closed


1

आम तौर पर बोलते हुए, मैं रास्ते के मापदंडों का उपयोग करता हूं, जब संसाधन में एक स्पष्ट 'पदानुक्रम' होता है, जैसे:

/region/state/42

यदि उस एकल संसाधन की स्थिति है, तो कोई भी हो सकता है:

/region/state/42/status

हालांकि, अगर 'क्षेत्र' वास्तव में उजागर किए जा रहे संसाधन का हिस्सा नहीं है, तो यह संभवतः क्वेरी मापदंडों में से एक है - पेजिनेशन के समान (जैसा कि आपने उल्लेख किया है)।


0

विभाजन अधिक पदानुक्रम और "सुंदर" है, लेकिन सीमित हो सकता है।

उदाहरण के लिए, यदि आपके पास तीन खंडों के साथ एक url है, तो प्रत्येक एक मेक, मॉडल और रंग के माध्यम से कार की खोज करने के लिए अलग-अलग मापदंडों को पार कर रहा है:

www.example.com/search/honda/civic/blue

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

www.example.com/search?color=blue
www.example.com/search?make=civic

अब आपके पास अपने क्वेरी कोड में "रंग" या "मेक" - कुंजी के माध्यम से मान को संदर्भित करने का एक तरीका है।

आप इस तरह के कुंजी मूल्य संरचना का एक प्रकार बनाने के लिए संभवतः अधिक सेगमेंट का उपयोग करके इसे प्राप्त कर सकते हैं:

www.example.com/search/make/honda/model/civic/color/blue

आशा है कि समझ में आता है ..


-2

उदाहरण URL: /rest/{keyword}

यह URL पथ पैरामीटर के लिए एक उदाहरण है। हम इस URL डेटा का उपयोग करके प्राप्त कर सकते हैं@PathParam

उदाहरण URL: /rest?keyword=java&limit=10

यह URL क्वेरी पैरामीटर के लिए एक उदाहरण है। हम इस URL डेटा का उपयोग करके प्राप्त कर सकते हैं @Queryparam

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