खोज एक RESTful इंटरफ़ेस में कैसे फिट होते हैं?


137

RESTful इंटरफ़ेस डिज़ाइन करते समय, अनुरोध प्रकारों के शब्दार्थ को डिज़ाइन के लिए महत्वपूर्ण माना जाता है।

  • प्राप्त करें - सूची संग्रह या तत्व को पुनः प्राप्त करें
  • PUT - संग्रह या तत्व को बदलें
  • पोस्ट - संग्रह या तत्व बनाएँ
  • DELETE - ठीक है, erm, संग्रह या तत्व को हटा दें

हालाँकि, यह "खोज" की अवधारणा को कवर नहीं करता है।

उदाहरण के लिए, नौकरी की खोज साइट का समर्थन करने वाली वेब सेवाओं का एक सूट डिजाइन करने में आपको निम्नलिखित आवश्यकताएं हो सकती हैं:

  • अलग-अलग जॉब एडवर्ट करें
    • को प्राप्त होता हैdomain/Job/{id}/
  • नौकरी का विज्ञापन बनाएँ
    • पोस्ट करने के लिएdomain/Job/
  • जॉब एडवर्ट को अपडेट करें
    • करने के लिए PUTdomain/Job/
  • नौकरी का विज्ञापन हटाएं
    • DELETE कोdomain/Job/

"सभी नौकरियां प्राप्त करें" भी सरल है:

  • को प्राप्त होता हैdomain/Jobs/

हालांकि, नौकरी "खोज" इस संरचना में कैसे आती है?

आप दावा कर सकते हैं कि यह "सूची संग्रह" की भिन्नता है और इसे इस प्रकार लागू किया जा सकता है:

  • को प्राप्त होता हैdomain/Jobs/

हालाँकि, खोज जटिल हो सकती है और एक लंबी GET स्ट्रिंग उत्पन्न करने वाली खोज का उत्पादन करना पूरी तरह से संभव है। यही है, यहाँ एक SO प्रश्न का संदर्भ देते हुए, लगभग 2000 वर्णों की तुलना में लंबे समय तक GET स्ट्रिंग्स का उपयोग करने के मुद्दे हैं।

एक उदाहरण एक मुखर खोज में हो सकता है - "नौकरी" उदाहरण जारी रखना।

मैं पहलुओं पर खोज करने की अनुमति दे सकता हूं - "प्रौद्योगिकी", "नौकरी का शीर्षक", "अनुशासन" के साथ-साथ मुक्त-पाठ कीवर्ड, नौकरी की आयु, स्थान और वेतन।

एक द्रव उपयोगकर्ता इंटरफ़ेस और बड़ी संख्या में तकनीकों और नौकरी के शीर्षक के साथ, यह संभव है कि एक खोज बड़ी संख्या में पहलू विकल्पों को शामिल कर सके।

सीवी के लिए इस उदाहरण को दोहराएं, नौकरियों के बजाय, और भी अधिक पहलुओं को लाएं, और आप बहुत आसानी से चुने गए सौ पहलुओं के साथ एक खोज की कल्पना कर सकते हैं, या यहां तक ​​कि सिर्फ 40 पहलुओं में से प्रत्येक 50 वर्ण लंबा हो सकता है (जैसे नौकरी के शीर्षक, विश्वविद्यालय के नाम, उदाहरण नियोक्ता के नाम)।

उस स्थिति में यह सुनिश्चित करने के लिए एक PUT या POST को स्थानांतरित करना वांछनीय हो सकता है ताकि यह सुनिश्चित हो सके कि खोज डेटा सही तरीके से भेजा जाएगा। उदाहरण के लिए:

  • पोस्ट करने के लिएdomain/Jobs/

लेकिन शब्दार्थ यह कि एक संग्रह बनाने के लिए एक निर्देश है।

आप यह भी कह सकते हैं कि आप इसे एक खोज के निर्माण के रूप में व्यक्त करेंगे:

  • पोस्ट करने के लिएdomain/Jobs/Search/

या (नीचे दिए गए बर्नग्राम द्वारा सुझाए गए)

  • पोस्ट करने के लिएdomain/JobSearch/

शब्दशः यह समझ में आ सकता है, लेकिन आप वास्तव में कुछ भी नहीं बना रहे हैं, आप डेटा के लिए अनुरोध कर रहे हैं।

इसलिए, शब्दार्थ यह एक GET है , लेकिन GET को उस समर्थन की गारंटी नहीं है जो आपको चाहिए।

तो, सवाल यह है - जितना संभव हो सके Restful design को सही रखने की कोशिश करते हुए, यह सुनिश्चित करते हुए कि मैं HTTP की सीमाओं के भीतर रख रहा हूँ, किसी खोज के लिए सबसे उपयुक्त डिज़ाइन क्या है?


3
मैं अक्सर GET का उपयोग करने का इरादा रखता हूं domain/Jobs?keyword={keyword}। यह मेरे लिए ठीक काम करता है :) मेरी आशा है, कि SEARCHक्रिया एक मानक बन जाएगी। programmers.stackexchange.com/questions/233158/…
Knerd

हां, मैं देख सकता हूं कि एक तुच्छ उदाहरण के लिए कोई समस्या नहीं है। लेकिन हम जिस टूल का निर्माण कर रहे हैं, वह वास्तव में अविश्वसनीय नहीं है कि हम एक जटिल खोज के साथ समाप्त हो जाएंगे जिसके परिणामस्वरूप 2000 वर्णों से अधिक लंबा स्ट्रिंग प्राप्त होगा। फिर क्या?
रोब बैली

वास्तव में एक बहुत अच्छी बात है। एक संपीड़न प्रौद्योगिकी को निर्दिष्ट करने के बारे में क्या?
Knerd

2
एक शरीर के साथ GET को एचटीटीपी युक्ति द्वारा अनुमति दी जाती है, मिडलवेयर (कभी-कभी नहीं) द्वारा समर्थित हो सकती है या नहीं की जा सकती है और इसे अभ्यास के रूप में पसंद नहीं किया जाता है। यह समय-समय पर Stackexchange पर आता है। stackoverflow.com/questions/978061/http-get-with-request-body
Rob

2
मैंने POST JobSearch को एक वास्तविक खोज इकाई बनाने और jobSearchId को वापस कर दिया है। फिर नौकरी प्राप्त करें? JobSearch = jobSearchId वास्तविक नौकरी संग्रह लौटाता है।
सेराड

जवाबों:


93

आपको यह नहीं भूलना चाहिए कि GET अनुरोधों के अन्य समाधानों पर कुछ बेहतर फायदे हैं:

1) जीईटी अनुरोधों को यूआरएल बार से कॉपी किया जा सकता है, वे खोज इंजन द्वारा पच जाते हैं, वे "अनुकूल" हैं। जहां "दोस्ताना" का अर्थ है कि आम तौर पर एक GET अनुरोध को आपके आवेदन (idempotent) के अंदर कुछ भी संशोधित नहीं करना चाहिए । यह खोज के लिए मानक मामला है।

2) ये सभी अवधारणाएं न केवल उपयोगकर्ता और खोज इंजन से, बल्कि एक वास्तुशिल्प, एपीआई डिजाइन दृष्टिकोण से बहुत महत्वपूर्ण हैं

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

यह सब देखते हुए मेरी सलाह होगी:

क) आपको चतुर पैरामीटर संरचना का उपयोग करके अपने GET के अंदर फिट होने में सक्षम होना चाहिए । चरम स्थिति में आप इस Google खोज की तरह रणनीति के लिए भी जा सकते हैं, जहां मैंने बहुत सारे पैरामीटर सेट किए हैं फिर भी यह एक सुपर शॉर्ट यूआरएल है।

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


व्यक्तिगत रूप से मैं अपने सभी पंजे के साथ लड़ने की कोशिश करूँगा ) और इसे पूरा करने के लिए ) और जब सभी आशा खो जाती है, तो मैं अपनी आँखों में आँसू के साथ वापस क्रॉल करूँगा विकल्प बी)


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

@RobBaillie ये ब्राउज़र केवल उपयोग का मामला था। मैं इस तथ्य को व्यक्त करना चाहता था कि एक URL स्ट्रिंग द्वारा संपूर्ण रूप में आपकी खोज का प्रतिनिधित्व किया जाता है। जो उत्तर में बाद में अन्य बिंदुओं के साथ प्रयोज्यता में बहुत आराम देता है।
p1100i

बिंदु b में, क्या POST के लिए मेरे स्वयं के संदर्भ में यह भिन्नता है domain/Jobs/Search/, शायद domain/JobsSearch/इसके साथ , या क्या आपका मतलब कुछ अलग था? क्या आप स्पष्ट कर सकते हो?
रोब बैली

7
मुझे यह क्यों आभास हो रहा है कि REST समस्या के समाधान के बजाय, अक्सर समस्या का हिस्सा है?
JensG

1
"GET अनुरोध को आपके आवेदन (idempotent) के अंदर कुछ भी संशोधित नहीं करना चाहिए" जबकि GET का अर्थ है, प्रासंगिक शब्द यहां " सुरक्षित " है। बेरोजगार का मतलब है कि एक संसाधन पर दो बार GET करना एक बार उस संसाधन पर GET करने के समान है। PUT भी उदासीन है, लेकिन सुरक्षित नहीं है, उदाहरण के लिए।
जस्मीजन

12

टीएल; डीआर: छानने के लिए जीईटी, खोज के लिए पोस्ट

मैं एक संग्रह बनाम एक जटिल खोज को सूचीबद्ध करने से परिणामों को फ़िल्टर करने के बीच एक अंतर करता हूं। लिटमस टेस्ट का उपयोग मैं मूल रूप से करता हूं, अगर मुझे फ़िल्टरिंग (सकारात्मक, नकारात्मक, या रेंज) से अधिक की आवश्यकता होती है, तो मैं इसे POST की आवश्यकता वाली एक अधिक जटिल खोज मानता हूं।

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

-

थोड़ी देर हो गई है और मेरा मूल पद थोड़ा टेढ़ा था इसलिए मैंने सोचा कि मैं अपडेट करूंगा।

GET अधिकांश प्रकार के डेटा, REST संसाधनों के संग्रह, संसाधन के संरचित डेटा, यहां तक ​​कि एकवचन पेलोड (चित्र, डॉक्स, आदि) के लिए सहज ज्ञान युक्त विकल्प है।

POST कुछ भी है जो GET, PUT, DELETE, आदि के तहत फिट नहीं लगता है के लिए catchall तरीका है।

इस बिंदु पर मुझे लगता है कि सरल खोजें, फ़िल्टरिंग GET के माध्यम से सहज ज्ञान युक्त बनाती हैं। यदि आप एकत्रीकरण कार्यों, क्रॉस सहसंबंधों (जॉइन), री-फॉर्मेटर्स, आदि में फेंक रहे हैं तो कॉम्प्लेक्स खोज व्यक्तिगत पसंद पर निर्भर करती है। मैं यह तर्क दूंगा कि जीईटी परमेस को बहुत लंबा नहीं होना चाहिए, और यह एक लार्जर क्वैश्चन है (हालांकि इसकी संरचना की जा रही है) ) अक्सर POST अनुरोध निकाय के रूप में अधिक समझ में आता है।

मैं एपीआई उपयोग के अनुभव पहलू पर भी विचार करता हूं। मैं आम तौर पर संभव के रूप में उपयोग करने के लिए और सहज ज्ञान युक्त के रूप में सबसे तरीकों बनाना चाहते हैं। मैं उन कॉलों को धक्का दूंगा जो POST में और अधिक लचीले (और इसलिए अधिक जटिल) हैं और एक अलग संसाधन URI पर, खासकर यदि यह उसी API में अन्य REST संसाधनों के व्यवहार के साथ असंगत है।

किसी भी तरह से, निरंतरता शायद इस बात से ज्यादा महत्वपूर्ण है कि आप GET या POST में खोज कर रहे हैं या नहीं।

उम्मीद है की यह मदद करेगा।


1
चूंकि REST अंतर्निहित कार्यान्वयन को दूर करने का इरादा है (उदाहरण के लिए - संसाधन आवश्यक रूप से डेटाबेस में एक पंक्ति या हार्ड ड्राइव पर एक फ़ाइल नहीं है, लेकिन कुछ भी हो सकता है ) मुझे नहीं पता कि यह जरूरी है कि POST का उपयोग करने के लिए समझ में आता है जब यह SQL जॉइन करने की बात आती है। मान लीजिए कि आपके पास स्कूलों की एक तालिका और बच्चों की एक तालिका है और आप एक कक्षा (एक स्कूल, कई बच्चे) चाहते हैं। आप आसानी से एक आभासी संसाधन को परिभाषित कर सकते हैं और GET /class?queryParams। एक उपयोगकर्ता के दृष्टिकोण से "वर्ग" हमेशा एक चीज थी और आपको कोई अजीब एसक्यूएल जॉइन नहीं करना था।
स्टेवेंडेसु

"फ़िल्टरिंग" और "खोज" के बीच कोई अंतर नहीं है।
निकोलस शंस

1
हां, एक फिल्टर मौजूदा क्षेत्रों पर आधारित है। एक खोज में बहुत अधिक जटिल पैटर्न हो सकते हैं, फ़ील्ड को संयोजित करना, सहायक मानों की गणना करना इत्यादि
user13796

@stevendesu वास्तव में, यही कारण है कि मैं दोनों के लिए POST का उपयोग करता हूं (एक खोज बना रहा हूं) :-)
ymajoros

जब तक आप खोज शब्दों और खोज के परिणामों को कहीं नहीं सहेज रहे हैं, तब तक मुझे पता नहीं है कि POST शब्दार्थ में अर्थपूर्ण है। जब आप खोज करते हैं तो आप जानकारी के लिए अनुरोध कर रहे हैं, आप कहीं भी बनाए रखने के लिए नई जानकारी प्रदान नहीं कर रहे हैं।
स्टीवेन्डेसू

10

REST में, संसाधन परिभाषा बहुत व्यापक है। यह वास्तव में है लेकिन आप कुछ डेटा बंडल करना चाहते हैं।

  • संग्रह संसाधन के रूप में खोज संसाधन के बारे में सोचना उपयोगी है। क्वेरी पैरामीटर, जिसे कभी-कभी URI के खोजे जाने योग्य हिस्से के रूप में कहा जाता है, ग्राहक को जिन वस्तुओं में रुचि होती है, उनके लिए संसाधन को सीमित करें।

उदाहरण के लिए, मुख्य Google यूआरआई "इंटरनेट पर हर साइट के लिंक" के संग्रह संसाधन की ओर इशारा करता है। क्वेरी पैरामीटर उन साइटों को संकीर्ण करते हैं जिन्हें आप देखना चाहते हैं।

(URI = यूनिवर्सल रिसोर्स आइडेंटिफ़ायर, जिनमें से URL = यूनिवर्सल रिसोर्स लोकेटर, जहाँ परिचित "http: //" URI के लिए डिफ़ॉल्ट फॉर्मेट है। तो URL लोकेटर है, लेकिन REST में किसी रिसोर्स आइडेंटिफ़ायर को सामान्य बनाने के लिए अच्छा है। हालांकि, लोग उन्हें परस्पर उपयोग करते हैं, हालांकि।)

  • चूंकि आप अपने उदाहरण में जिस संसाधन को खोज रहे हैं, वह नौकरी संग्रह है, यह खोज करने के लिए समझ में आता है

साइट / नौकरियां प्राप्त करें? टाइप करें = ब्लाह और स्थान = यहाँ और आदि = आदि

(वापसी) {नौकरियां: [{नौकरी: ...}]}

और फिर POST का उपयोग करें, जो उस संग्रह में नई वस्तुओं को जोड़ने के लिए ऐप या प्रक्रिया है:

POST साइट / नौकरियां

{काम: ...}

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

  • वास्तव में लंबे या जटिल क्वेरी स्ट्रिंग्स के लिए, कन्वेंशन उन लोगों को पोस्ट के अनुरोध के रूप में भेजने के लिए ठीक बनाता है। क्वेरी पैरामीटर्स को नाम / मान जोड़े के रूप में बंडल करें, या किसी JSON या XML संरचना में नेस्टेड ऑब्जेक्ट्स और अनुरोध के शरीर में भेजें। उदाहरण के लिए, यदि आपकी क्वेरी में नाम / मान जोड़े के एक समूह के बजाय डेटा नेस्टेड है। POST के लिए HTTP युक्ति इसे परिशिष्ट या प्रक्रिया क्रिया के रूप में वर्णित करता है। (यदि आप REST में एक खामियों के माध्यम से युद्धपोत पालना चाहते हैं, तो POST का उपयोग करें।)

हालांकि, मैं इसे फालबैक प्लान के रूप में उपयोग करूंगा।

जब आप ऐसा करते हैं तो आप क्या खो देते हैं, हालांकि) GET अशक्त है - अर्थात, यह कुछ भी नहीं बदलता है - POST नहीं है। यदि कॉल विफल हो जाता है, तो मिडलवेयर स्वचालित रूप से पुनर्प्रयास या कैश परिणाम नहीं देगा, और 2) शरीर में खोज मापदंडों के साथ, आप अब URI को काट और पेस्ट नहीं कर सकते। यही है, URI आपके इच्छित खोज के लिए कोई विशिष्ट पहचानकर्ता नहीं है।

"खोज" से "बनाएँ" के बीच अंतर करने के लिए। कुछ विकल्प हैं जो REST अभ्यास के अनुरूप हैं:

  • आप इसे यूआरआई में संग्रह के नाम पर कुछ जोड़कर कर सकते हैं, जैसे नौकरियों के बजाय नौकरी-खोज। इसका मतलब है कि आप खोज संग्रह को एक अलग संसाधन के रूप में मान रहे हैं।

  • चूंकि POST का शब्दार्थ दोनों परिशिष्ट या प्रक्रिया है, आप पेलोड के साथ खोज निकायों की पहचान कर सकते हैं। जैसे {job: ...} बनाम {search: ...}। इसे पोस्ट करने या इसे उचित रूप से संसाधित करने के लिए POST तर्क पर निर्भर है।

यह बहुत ज्यादा एक डिजाइन / कार्यान्वयन प्राथमिकता है। मुझे नहीं लगता कि एक स्पष्ट सम्मेलन है।

तो, जैसे आपने पहले ही तय कर लिया है, विचार के लिए एक संग्रह संसाधन को परिभाषित करना है jobs

साइट / नौकरियों

खोज को संकीर्ण करने के लिए GET + क्वेरी परमेस के साथ खोजें। लंबी या संरचित डेटा क्वेरी POST (संभवतः एक अलग खोज संग्रह में) के शरीर में जाती हैं। संग्रह में संलग्न करने के लिए POST के साथ बनाएँ। और PUT के साथ एक विशिष्ट URI के लिए अद्यतन करें।

(एफडब्ल्यूआईडब्ल्यू यूआरआई के साथ स्टाइल कन्वेंशन को हाइफ़न द्वारा अलग किए गए शब्दों के साथ सभी लोअरकेस का उपयोग करना है। लेकिन इसका मतलब यह नहीं है कि आपको इसे इस तरह से करना होगा।)

(इसके अलावा, मुझे कहना चाहिए कि आपके प्रश्न से, यह स्पष्ट है कि आप इस सड़क से बहुत दूर हैं। मैंने चीजों को स्पष्ट रूप से केवल उन्हें पंक्तिबद्ध करने के लिए स्पष्ट किया है, लेकिन आपके प्रश्न ने पहले से ही इसमें अधिकांश शब्दार्थों को संबोधित किया था। जवाब। मैं बस इसे कुछ सम्मेलन और अभ्यास के साथ रख रहा था।)


यह एक दिलचस्प विचार है - मैंने पेलोड को अंतर करने के लिए उपयोग करने पर विचार नहीं किया होगा। यह लगभग थोड़ा अंडरहैंड लगता है! लेकिन मुझे लगता है कि URI योजना में वास्तव में कोई क्रिया नहीं है - यह अनुरोध प्रकार है जो क्रिया को परिभाषित करता है। हो सकता है कि यूआरआई की तुलना में पेलोड शब्दबद्ध रूप से अनुरोध के करीब हो। एकमात्र चिंता यह है - क्या यह एपीआई के उपयोगकर्ता के लिए पारदर्शी है?
रोब बैली

कार्यान्वयन के संदर्भ में (हम नोड और एक्सप्रेस का उपयोग कर रहे हैं), इसका मतलब यह हो सकता है कि routeवास्तव में प्रसंस्करण की पसंद को नहीं संभाल सकता है । मैं उस पर एक नज़र रखना होगा ...
रोब Baillie

मैं एक ही आंत लग रहा है, कि URI द्वारा इसे अलग करने से क्लीनर लगता है। मैं पीछे-पीछे जा रहा हूं; यह एक निर्णय कॉल है। हालाँकि, HTTP के शब्दार्थ इसे शरीर में लगाने की अनुमति देते हैं। मुझे कहना पसंद है, REST वर्ल्ड वाइड वेब के बाद मॉडलिंग की है, और WWW GET और POST के साथ बनाया गया था।
रोब

8

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

आप टोकन का उपयोग करते हैं जैसे कि $select=और $filter=आप एक URI के साथ समाप्त होंगे जो कुछ इस तरह दिखता है:

/users?$select=Id,Name$filter=endswith(Name, 'Smith')

तुम भी उपयोग कर रहा पेजिंग कर सकते हैं $skipऔर $topऔर आदेश।

अधिक जानकारी के लिए, OData.org देखें । आपने यह निर्दिष्ट नहीं किया है कि आप किस भाषा का उपयोग कर रहे हैं, लेकिन यदि वह ASP.NET है, तो WebApi प्लेटफ़ॉर्म OData प्रश्नों का समर्थन करता है - दूसरों के लिए (PHP आदि) संभवतः लाइब्रेरीज़ हैं जिन्हें आप डेटाबेस प्रश्नों में अनुवाद करने के लिए उपयोग कर सकते हैं।


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

@RobBaillie मुझे नहीं लगता है क्योंकि यह अभी भी एक क्वेरी स्ट्रिंग के साथ एक GET कॉल है। मैं सुझाव दूंगा कि आप ओडटा का उपयोग जहां भी कर सकते हैं, यह वेब डेटा स्रोतों को क्वेरी करने के लिए एक मानक है और कुछ के लिए (यदि कोई है) तो क्वेरी को इतना जटिल बनाने की आवश्यकता है कि आप इसे 2000 वर्ण क्वेरी में फिट नहीं कर सकते, एक विशिष्ट बनाएं एंडपॉइंट जिसे आप GET कॉल करते हैं
ट्रेवर पिली

क्या आप अपने दृष्टिकोण को "विशिष्ट समापन बिंदु के लिए समझा सकते हैं जिसे आप GET कॉल करते हैं"? आप कैसे सोच सकते हैं कि समापन बिंदु दिखेगा?
रोब बैली

@RobBaillie सुनिश्चित करें - फिर से मुझे यकीन नहीं है कि आप किस तकनीक का उपयोग कर रहे हैं, लेकिन ASP.NET में मैं एक विशिष्ट नियंत्रक बनाऊंगा जिसे JobsNearMeAddedInTheLast7Daysया जो क्वेरी को लंबा करना है जो ओडटा के लिए बहुत लंबा / जटिल है और फिर इसे केवल GET कॉल के माध्यम से उजागर करें ।
ट्रेवर पिली

1
समझा। एक और दिलचस्प विचार यह है कि शायद कुछ पैर हैं, हालांकि मुझे यकीन नहीं है कि यह मेरे विशेष मामले में मदद करेगा - बहुत सारे पहलू प्रकारों और बहुत सारे संभावित पहलुओं के साथ खोज करना
रोब बैली

5

विचार करने के लिए एक दृष्टिकोण संग्रह संसाधन के रूप में संभावित प्रश्नों के सेट को मान रहा है, जैसे /jobs/filters

POSTइस संसाधन के लिए अनुरोध, शरीर में क्वेरी मापदंडों के साथ, या तो एक नया संसाधन बनाएगा या एक मौजूदा समकक्ष फ़िल्टर की पहचान करेगा और एक आईडी वाला URL लौटाएगा /jobs/filters/12345:।

आईडी का उपयोग नौकरियों के लिए GET अनुरोध में किया जा सकता है /jobs?filter=12345:। GETफ़िल्टर संसाधन पर अनुवर्ती अनुरोध फ़िल्टर की परिभाषा वापस कर देंगे।

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

इस दृष्टिकोण के लिए एक दोष यह है कि आप URL की पठनीयता खो देते हैं (हालांकि यह GETफ़िल्टर संसाधन के लिए एक अनुरोध के रूप में परिभाषा को पुनः प्राप्त करके कम किया जा सकता है )। इस कारण से आप /jobsसंसाधन पर क्वेरी पैरामीटर के समान या सबसेट का समर्थन करना चाहते हैं क्योंकि आप फ़िल्टर संसाधन के लिए समर्थन करेंगे। यह छोटे प्रश्नों के लिए इस्तेमाल किया जा सकता है। यदि यह सुविधा प्रदान की जाती है, तो /jobsसंसाधन पर क्वेरी मापदंडों का उपयोग करते समय, दो प्रकार के फ़िल्टरिंग के बीच कैचेबिलिटी बनाए रखने के लिए , कार्यान्वयन को फ़िल्टर संसाधन को आंतरिक रूप से बनाना / पुन: उपयोग करना चाहिए और URL के रूप में इंगित करने वाले एक 302या 303स्थिति को वापस करना चाहिए /jobs?filter=12345


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

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

आप केवल फ़िल्टर करके स्टोर करने की आवश्यकता को दूर कर सकते हैं ... उन्हें संग्रहीत नहीं कर सकते। REST के बारे में कुछ भी गारंटी नहीं है कि यह लगातार है। आप इसके लिए एक अनुरोध कर सकते हैं GET /jobs/37और एक परिणाम प्राप्त कर सकते हैं, फिर कोई व्यक्ति संसाधन को हटा देता है और 2 सेकंड बाद उसी अनुरोध को 404 देता है। इसी तरह यदि आप POST /searchesऔर आप एक खोज परिणाम पर पुनर्निर्देशित होते हैं (खोज बनाई जाती है और आपको एक 201 प्राप्त होता है संसाधन हेडर से संसाधन), 2 सेकंड बाद उस परिणाम को मेमोरी से मिटा दिया जा सकता है और उसे फिर से बनाना होगा। लंबी अवधि के भंडारण के लिए कोई ज़रूरत नहीं है।
स्टेवेंडेसु

5

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

किसी खोज को बेहतर तरीके से वर्णन करने के लिए हमें विशेष रूप से एक आर्किटेक्चर के बारे में बात करनी होगी और जो बेहतर होगा वह है रिसोर्स ओरिएंटेड आर्किटेक्चर (आरओआर)।

Restful में डिजाइन करने के सिद्धांत हैं, idempotent का मतलब यह नहीं है कि परिणाम बदल नहीं सकते हैं क्योंकि मैं कुछ उत्तरों में पढ़ता हूं, इसका मतलब है कि एक स्वतंत्र अनुरोध का परिणाम इस बात पर निर्भर नहीं करता है कि कितनी बार निष्पादित किया गया है। यह बदल सकता है, आइए कल्पना करें कि मैं एक डेटाबेस को लगातार अद्यतन कर रहा हूं जो कि कुछ डेटा के साथ फीड कर रहा है जो कि Restful Api द्वारा परोसा जाता है, उसी GET को निष्पादित करने से परिणाम बदल सकता है लेकिन यह निर्भर नहीं करता है कि इसे कितनी बार निष्पादित किया गया है। अगर मैं दुनिया को फ्रीज करने में सक्षम हूं तो इसका मतलब है कि कोई भी स्थिति, परिवर्तन, सेवा के अंदर कुछ भी नहीं है जब मैं संसाधन का अनुरोध करता हूं जो एक अलग परिणाम की ओर ले जाता है।

परिभाषा के अनुसार, एक संसाधन कुछ भी है जिसे स्वयं के रूप में संदर्भित किया जाना महत्वपूर्ण है।

संसाधन उन्मुख वास्तुकला में (इसे संक्षिप्तता के लिए अब से आरओए कहें) हम उस संसाधन पर ध्यान केंद्रित करते हैं जो बहुत कुछ हो सकता है:

  • एक दस्तावेज़ का एक संस्करण
  • दस्तावेज़ का अंतिम अद्यतन संस्करण
  • एक खोज से आने वाला परिणाम
  • वस्तुओं की एक सूची
  • पहला लेख मैंने ई-कॉमर्स से खरीदा था

क्या यह संसाधन के मामले में अनूठा बनाता है addresability जिसका मतलब है कि यह है केवल एक यूआरआइ

इस तरह से खोज ROA को देखते हुए Restful में पूरी तरह से फिट बैठता है । हमें GET का उपयोग करना होगा क्योंकि मैं मान रहा हूं कि आपकी खोज एक सामान्य खोज है और यह कुछ भी नहीं बदलती है, इसलिए यह आदर्श है (भले ही यह नए तत्वों के आधार पर अलग-अलग चीजें लौटाता है)। इस तरह से यहां एक भ्रम है क्योंकि मैं RESTful से चिपक सकता हूं और ROA से नहीं, इसका मतलब है कि मैं एक पैटर्न का पालन कर सकता हूं जो एक खोज बनाता है और एक ही पैरामीटर के साथ विभिन्न चीजों को वापस करता है क्योंकि मैं आरओए के पते के सिद्धांत का उपयोग नहीं कर रहा हूं। यह कैसा है? ठीक है, यदि आप शरीर में खोज फ़िल्टर भेजते हैं या शीर्ष लेख संसाधन नहीं है।

आप डब्ल्यू 3 मूल दस्तावेज में वास्तव में और यूआरआई के सिद्धांतों को पा सकते हैं:

https://www.w3.org/DesignIssues/Axioms

इस आर्किटेक्चर के किसी भी URL को स्व-वर्णनात्मक होना चाहिए। यदि आप URI में सब कुछ को संबोधित करने के लिए सिद्धांतों का पालन करते हैं तो यह आवश्यक है, इसका मतलब है कि आप जो कुछ भी चाहते हैं या क्वेरी पैरामीटर को अलग करने के लिए / (स्लैश) का उपयोग कर सकते हैं। हम जानते हैं कि उस पर सीमाएँ हैं, लेकिन यह वास्तुकला पैटर्न है।

RESTful में ROA पैटर्न का अनुसरण करना किसी भी अन्य संसाधन से अधिक नहीं है, केवल अंतर यह है कि संसाधन ऑब्जेक्ट से प्रत्यक्ष संबंध के बजाय एक संगणना से आते हैं। सिद्धांत के आधार पर मैं निम्नलिखित पैटर्न के आधार पर एक सरल अंकगणितीय गणना सेवा को संबोधित और प्राप्त कर सकता हूं:

http://myapi.com/sum/1/2

जहां योग, 1 और 2 को संशोधित किया जा सकता है, लेकिन गणना का परिणाम अद्वितीय है और यह प्रशंसनीय है, हर बार जब मैं समान मापदंडों के साथ कॉल करता हूं तो मुझे समान मिलता है और सेवा में कुछ भी नहीं बदलता है। सिद्धांतों को पूरी तरह से resouce / sum / 1/2 और / substract / 5/4 छड़ी।


3

GET ठीक है, यदि आपके पास एक स्थिर संग्रह है जो हमेशा एक ही URI के लिए समान परिणाम (प्रतिनिधित्व) लौटाता है। इसका तात्पर्य यह भी है कि इन अभ्यावेदन को उत्पन्न करने वाला डेटा कभी भी परिवर्तित नहीं होता है। स्रोत केवल-पढ़ने के लिए डेटाबेस है।

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

एक आम खोज एक POST अनुरोध के साथ शुरू होती है जो परिणाम का संदर्भ देता है। यह परिणाम उत्पन्न करता है (यह नया है और बाद में GET के साथ लाया जा सकता है)। यह परिणाम पदानुक्रमित हो सकता है (यूआरआई के साथ आगे के संदर्भ जो आप प्राप्त कर सकते हैं), निश्चित रूप से, और पहले की खोजों के तत्वों का पुन: उपयोग कर सकते हैं, अगर यह आवेदन के लिए समझ में आता है।

वैसे, मुझे पता है कि लोग इसे अलग तरह से करते हैं। आपको यह समझाने की जरूरत नहीं है कि REST का उल्लंघन करना कितना सुविधाजनक हो सकता है।


Aaaaaaaah - तो यह कैसे काम करने वाला है! धन्यवाद!
रॉब बालि

1
Idempotency का मतलब यह नहीं है कि उसे हमेशा वही लौटना है, यदि परिवर्तन नहीं होता है तो उसे वापस लौटना होगा। खोज को संगणना का परिणाम माना जा सकता है और यह एक संसाधन ही है।
मैक्सिमिलियानो रियोस

वास्तव में आय का अर्थ है कि परिणाम समान रहता है। कैश नियंत्रण का उपयोग करने के लिए आप कर सकते हैं, और यह व्यावहारिक है। और आप निश्चित रूप से DELETE का उपयोग कर सकते हैं जो बाद के GET के साथ हस्तक्षेप करता है। यदि फिर भी, एक एजेंट को आवेदन के आंतरिक कामकाज के बारे में ज्ञान रखने की आवश्यकता है, तो यह अब और उपयोगी नहीं है। ऊपर, मैं REST के सबसे चरम विचार के बारे में बात कर रहा था। व्यवहार में, लोग इसके कई पहलुओं का उल्लंघन कर सकते हैं। वे उस कीमत का भुगतान कर रहे हैं जब कैश अब कुशलतापूर्वक कैश नहीं करता है।
मार्टिन सुगियोर्तो

"Idempotency का वास्तव में मतलब है कि परिणाम समान रहता है।" ... अनुरोध के बाद। मेरा मानना ​​है कि अनुरोध डेटा को परिवर्तित नहीं करता है।
आंद्रेईमोटिंगा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.