2009-08-18 11 views
45

मैं एक नए वेब एप्लिकेशन पर रीस्टफुल सिद्धांतों को लागू करने के लिए संघर्ष कर रहा हूं, जिस पर मैं काम कर रहा हूं। विशेष रूप से, यह विचार है कि रीस्टफुल होने के लिए, प्रत्येक HTTP अनुरोध को अपने प्राप्तकर्ता के लिए HTTP की स्टेटलेस प्रकृति के साथ पूर्ण सद्भाव में प्रक्रिया करने के लिए पर्याप्त जानकारी लेनी चाहिए।REST - जटिल अनुप्रयोग

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

साथ ही, रोगी जानकारी के रोगियों उम्र, लिंग सहित प्रवेश किया जा सकता है, मौजूदा दवाओं आदि

शोकहारा हो, यह सभी जानकारी प्रत्येक अनुरोध के साथ शामिल किया जाना चाहिए? ऐसा लगता है कि नेटवर्क पर एक विशाल ओवरहेड है। साथ ही, कम से कम जीईटी के लिए यूआरएल लंबाई पर प्रतिबंध नहीं होगा, यह असुरक्षित बनाओ?

उत्तर

73

"फ़िल्टर के रूप में फ़िल्टर" इस ​​के लिए एक आदर्श रणनीति है।

आप फ़िल्टर संसाधन को फ़िल्टर परिभाषा डाल सकते हैं, और यह फ़िल्टर आईडी वापस कर सकता है।

पुट idempotent है, तो अगर फ़िल्टर पहले से ही है, तो आपको बस यह पता लगाने की जरूरत है कि आपने पहले फ़िल्टर देखा है, ताकि आप फ़िल्टर के लिए उचित आईडी वापस कर सकें।

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

प्राप्त/दवाओं? फिल्टर = 1234 & पेज = 4 & pagesize = 20

मैं, कैनॉनिकलाइज़ेशन प्रक्रिया किसी तरह की कच्चे फिल्टर चल पाएंगे सिर्फ एक सामान्यीकृत सेट है, ताकि, उदा फ़िल्टर "firstname = बॉब lastname = Eubanks" "lastname = Eubanks firstname = Bob" के समान है। हालांकि यह सिर्फ मुझे है।

एकमात्र असली चिंता यह है कि, जैसे ही समय चल रहा है, आपको कुछ फ़िल्टर अप्रचलित करने की आवश्यकता हो सकती है। आप अनुरोध को गलती कर सकते हैं कि किसी को लापता या अप्रचलित फ़िल्टर के साथ अनुरोध करना चाहिए।

संपादित का जवाब सवाल ...

की बुनियादी बातों के साथ शुरू करते हैं।

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

प्रभावी रूप से, आपको हमेशा क्वेरी पर फ़िल्टर भेजने की आवश्यकता होती है। सवाल यह है कि उस फ़िल्टर का प्रतिनिधित्व कैसे करें।

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

एक सत्र के साथ, आप (आमतौर पर) उस कुकी का प्रतिनिधित्व करने के लिए कुकी, या शायद कुछ अन्य टोकन वापस ले लेंगे। यदि दवा संसाधनों के लिए आपके पुट ने एक सत्र भी बनाया, तो सच में, आपके अनुरोध ने दो संसाधन बनाए: एक दवा, और एक सत्र।

दुर्भाग्य से, जब आप कुकी की तरह कुछ उपयोग करते हैं, और आपको अपने अनुरोध के लिए उस कुकी की आवश्यकता होती है, तो संसाधन का नाम अब संसाधन का सही प्रतिनिधित्व नहीं होता है। अब यह संसाधन नाम (यूआरएल), और कुकी है।

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

अब, आप शायद नाम लिख सकते हैं:/दवाएं/खोज? सत्र = एबीसी 123, संसाधन नाम में कुकी को प्रभावी रूप से एम्बेड कर रहा है।

लेकिन अब आप सत्रों के ठेठ अनुबंध में भाग लेते हैं, विशेष रूप से कि वे कम रहते हैं। तो, नामित संसाधन कम उपयोगी, दीर्घकालिक, बेकार नहीं है, केवल कम उपयोगी है। अभी, यह क्वेरी मुझे दिलचस्प डेटा देता है। आने वाला कल? शायद ऩही। सत्र समाप्त होने के बारे में मुझे कुछ ग़लत त्रुटि मिलेगी।

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

अब, इसे अपने सिर पर थोड़ा सा चालू करें। आइए उपयोग/दवाएं/खोज करें? फ़िल्टर = एबीसी 123।

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

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

तो, आप देख सकते हैं कि, 30,000 फीट पर, फ़िल्टर और सत्र के बीच मामले में बहुत अंतर नहीं है। लेकिन जब आप ज़ूम इन करते हैं, तो वे काफी अलग होते हैं।

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

यदि मैं ऐसा कर रहा था, तो मैं फ़िल्टर के साथ कैसे काम करूंगा?

मुझे लगता है कि मुझे वास्तव में फ़िल्टर की सामग्री की परवाह नहीं है। विशेष रूप से, मुझे संदेह है कि मैं कभी भी "पहले नाम से खोजे जाने वाले सभी फ़िल्टर" के लिए पूछताछ करूंगा। इस समय, यह अनिच्छुक जानकारी की तरह लगता है, इसलिए मैं इसके चारों ओर डिजाइन नहीं करूंगा।

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

फिर, मैं फ़िल्टर को एक्सएमएल या जेएसओएन दस्तावेज़ के रूप में स्टोर करता हूं, जो भी एप्लिकेशन के लिए अधिक आरामदायक/उपयुक्त है। मैं प्रत्येक फिल्टर को एक अनूठी कुंजी (स्वाभाविक रूप से) देता हूं, लेकिन मैं फ़िल्टर के साथ वास्तविक दस्तावेज़ के लिए हैश स्टोर भी करता हूं।

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

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

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

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

आशा है कि यह आपके लिए इस मुद्दे को स्पष्ट करे।

+4

यह सबसे अच्छा स्पष्टीकरण है जो मैंने देखा है कि क्यों सत्र एक आरईएसटी स्टाइल आर्किटेक्चर में फिट नहीं होते हैं। –

+0

+1: बढ़िया जवाब, विल! –

+0

अच्छी व्याख्या @Will – jayraynet

10

REST एपीआई के लिए है, नहीं (सामान्य) अनुप्रयोग। एक stateless मॉडल में मूल रूप से राज्यव्यापी बातचीत को रोकने की कोशिश न करें क्योंकि आप विकिपीडिया पर इसके बारे में पढ़ते हैं।

आराम करने के लिए, क्या यह जानकारी हर अनुरोध के साथ शामिल की जानी चाहिए? ऐसा लगता है कि नेटवर्क पर एक विशाल ओवरहेड है। साथ ही, कम से कम जीईटी के लिए यूआरएल लंबाई पर प्रतिबंध नहीं होगा, यह असुरक्षित बनाओ?

पैरामीटर का आकार आमतौर पर सर्वर के संसाधनों के आकार की तुलना में महत्वहीन होता है। यदि आप ऐसे बड़े मानकों का उपयोग कर रहे हैं कि वे नेटवर्क बोझ हैं, तो उन्हें पर पर रखें और फिर संसाधनों के रूप में उनका उपयोग करें।

URL लंबाई पर कोई महत्वपूर्ण प्रतिबंध नहीं हैं - यदि आपके सर्वर की ऐसी सीमा है, तो इसे अपग्रेड करें। यह शायद साल पुराना है और वैसे भी सुरक्षा भेद्यता से भरा हुआ है।

+2

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

+1

आरईएसटी एपीआई के लिए आरपीसी का विकल्प है; यह वेब के वास्तुकला का विवरण है। वेब अनुप्रयोगों को शायद ही कभी अपने वास्तुकला में वेब जैसा दिखता है, और रीस्टफुल इंटरैक्शन के लिए उपयुक्त नहीं है। "मौलिक रूप से राज्यव्यापी" के बारे में: प्रश्न से, ऐसा लगता है कि फ़िल्टर एक राज्य में जमा होते हैं और फिर एक सेट पर लागू होते हैं। मेरे लिए, एक स्टेटलेस सिस्टम में प्रदर्शित किया जा सकता है कि सबसे अच्छा तरीका एक "सेट" संसाधन बनाकर और फ़िल्टर को लागू करना है - ओपी के कार्यान्वयन से बहुत अलग है। –

+3

@ जॉन यदि आप वास्तव में आरईएसटी में रूचि रखते हैं तो मेरा सुझाव है कि आप फिर से रॉय के शोध प्रबंध को पढ़ लें और पढ़ें। मुझे लगता है कि आप गलत समझा। –

0

क्या आप एक विश्वसनीय API पर काम कर रहे हैं कि अन्य ऐप्स आपके डेटा को खोजने के लिए उपयोग करेंगे? या आप एक अंत उपयोगकर्ता केंद्रित वेब एप्लिकेशन बना रहे हैं जहां उपयोगकर्ता लॉग इन करेंगे और इन खोजों को निष्पादित करेंगे?

यदि आपके उपयोगकर्ता लॉग इन कर रहे हैं, तो आप पहले से ही सतर्क हैं क्योंकि लॉग इन स्थिति को बनाए रखने के लिए आपके पास कुछ प्रकार की सत्र कुकी होगी। मैं आगे बढ़ूंगा और एक सत्र ऑब्जेक्ट तैयार करूंगा जिसमें सभी खोज फ़िल्टर होंगे। यदि किसी उपयोगकर्ता ने कोई फ़िल्टर सेट नहीं किया है, तो यह ऑब्जेक्ट खाली हो जाएगा।

यहां जीईटी बनाम पोस्ट का उपयोग करने के बारे में एक महान ब्लॉग पोस्ट है। यह 2,048 वर्णों के इंटरनेट एक्सप्लोरर द्वारा निर्धारित यूआरएल लम्बाई सीमा का उल्लेख करता है, इसलिए आप लंबे अनुरोधों के लिए POST का उपयोग करना चाहते हैं।

http://carsonified.com/blog/dev/the-definitive-guide-to-get-vs-post/

5

नहीं है, उन सभी को हर अनुरोध में होने की जरूरत नहीं है।

प्रत्येक संसाधन (दवा, रोगी इतिहास, आदि) में एक कैननिकल यूआरआई होना चाहिए जो विशिष्ट रूप से इसकी पहचान करे। कुछ अनुप्रयोगों में (उदाहरण के लिए, रेल-आधारित वाले) यह कुछ "/ रोगी/1234" या "/ दवा/5678" जैसा होगा लेकिन यूआरएल प्रारूप महत्वहीन है।

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

+0

यह समझ में आता है। इसलिए जब वस्तुओं को गतिशील रूप से उत्पन्न किया जा सकता है (कोई उपयोगकर्ता फ़िल्टर की संख्या बना सकता है), ऐसा लगता है जैसे प्रत्येक को एक अद्वितीय यूआरआई असाइन करने की आवश्यकता होगी। यह यूआरआई क्लाइंट ऐप पर वापस भेज दिया जाएगा। क्या वो सही है? – Alistair77

+0

@ alistair77: सही। जब उपयोगकर्ता फ़िल्टर बनाता है, तो इसका प्रतिनिधित्व करने के लिए उस स्थान का प्रतिनिधित्व 'स्थान' हेडर के साथ वापस किया जाना चाहिए ताकि यह इंगित किया जा सके कि फ़िल्टर बाद के परिचालनों के लिए कहां पाया जा सकता है। –

12

आराम करने के लिए, क्या यह जानकारी हर अनुरोध के साथ शामिल की जानी चाहिए?

नहीं। अगर ऐसा लगता है अपने सर्वर की तरह भेजने के (या प्राप्त) है बहुत अधिक जानकारी, संभावना है कि एक या अधिक संसाधनों आप की पहचान अभी तक नहीं किया है कि कर रहे हैं।

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

  • उपयोगकर्ता - प्रणाली के एक उपयोगकर्ता (शायद एक डॉक्टर या रोगी():

    अपने विवरण से, यहां संसाधनों में से एक संभव सेट है? संसाधन यहां)

  • दवा - बोतल में सामान, लेकिन यह बोतल (मात्रा और सामग्री) की तरह भी प्रतिनिधित्व कर सकता है, या यह एक विशेष बोतल का प्रतिनिधित्व कर सकता है - यदि आप फार्मेसी हैं या सिर्फ एक सहायता केंद्र।
  • रोग - शर्त है जो के लिए एक रोगी एक दवा लेने के लिए चाहते हो सकता है।
  • रोगी - एक व्यक्ति जो एक दवा
  • सिफ़ारिश लग सकता है - एक दवा कि एक रोग वे से पीड़ित के आधार पर एक रोगी के लिए फायदेमंद हो सकता है।

फिर आप संसाधनों के बीच संबंधों को देख सकते हैं;

  • उपयोगकर्ता है और कई भूमिकाओं के अंतर्गत आता है
  • दवा है और कई रोग
  • रोग कई अनुशंसाएँ है के अंतर्गत आता है।
  • रोगी है और कई दवाएं और रोग (गरीब अध्याय)
  • रोगी है कई अनुशंसाएँ
  • सिफ़ारिश एक रोगी है और एक रोग है के अंतर्गत आता है

विनिर्देश शायद आपकी विशेष समस्या के लिए सही नहीं हैं, लेकिन विचार सरल है: अपने संसाधनों के बीच संबंधों का नेटवर्क बनाएं।

इस बिंदु यह यूआरआई संरचना के बारे में सोचने के लिए उपयोगी हो सकता है, हालांकि यह ध्यान रखें कि REST APIs must be hypertext-driven में रखने पर:

# view all Recommendations for the patient 
GET http://server.com/patients/{patient}/recommendations 

# view all Recommendations for a Medication 
GET http://servier.com/medications/{medication}/recommendations 

# add a new Recommendation for a Patient 
PUT http://server.com/patients/{patient}/recommendations 

क्योंकि यह बाकी है, तो आप अपना समय defining the media types का निरूपण हस्तांतरण के लिए किया अधिकांश समय बिताएंगे ग्राहक और सर्वर के बीच आपके संसाधन।

अधिक संसाधनों को उजागर करके, आप प्रत्येक अनुरोध के दौरान स्थानांतरित होने की आवश्यकता वाले डेटा की मात्रा को घटा सकते हैं। यह भी ध्यान दें कि यूआरआई में कोई प्रश्न पैरामीटर नहीं हैं। सर्वर राज्य के रूप में हो सकता है क्योंकि इसे सभी का ट्रैक रखने की आवश्यकता है, और प्रत्येक अनुरोध पूरी तरह आत्मनिर्भर हो सकता है।