2009-05-08 9 views
43

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

/users/48573 

और अब यह समस्या सिर्फ

तरह
/users/thisisausername. 

कि हम अभी भी किसी भी तरह संख्यात्मक आईडी के माध्यम से उन्हें लाने के लिए सक्षम होना चाहिए है लग रहा है , एपीआई के विरासत उपभोक्ताओं के लिए। हम बाकी यूआरएल खुद को रीडायरेक्ट करने के लिए (जैसे /users/48573/users/thisisausername पर पुन: निर्देशित नहीं होना चाहिए) की जरूरत नहीं है, हम सिर्फ पुराने पहचानकर्ता का उपयोग करके सही डेटा प्राप्त करने के लिए एक विधि की जरूरत है। समाधान या तो आईडी द्वारा उपयोगकर्ता जानकारी (जिसमें आसानी से नया पहचानकर्ता, उपयोगकर्ता नाम शामिल है) तक पहुंचने का एक वैकल्पिक तरीका प्रदान करना चाहिए, या आईडी द्वारा उपयोगकर्ता नाम तक पहुंच बनाना चाहिए। कुछ संभावित समाधान हो सकते हैं:

  • पहचान के कुछ वैकल्पिक तरीके को निर्दिष्ट करने के लिए नोड का उपयोग करना, उदा। /users/byid/48573
  • पहचान के कुछ वैकल्पिक विधि निर्दिष्ट करने के लिए एक क्वेरी पैरामीटर का उपयोग करना, जैसे /users/48573?fetchby=id या /users/48573?byid=true
  • एक और संसाधन हैं, उदाहरण के रूप में उपयोगकर्ता नाम-दर-आईडी का इलाज /identifiers/username/48573

इनमें से कौन सा (यदि कोई है) उचित REST के निकट है? आप समस्या से कैसे निपटेंगे?

+4

मैं एक खोज के रूप में गैर-प्रमुख-पहचानकर्ता क्षेत्रों के माध्यम से पहुंच को लागू करने को समाप्त कोडित है। यह समाधान एकाधिक क्षेत्रों के माध्यम से कई प्रकार के संसाधनों को लाने के लिए अनुमति देता है, जबकि प्राथमिक पहचानकर्ता के रूप में केवल एक को बनाए रखने के लिए। स्थिरता के लिए, "खोज" एपीआई सूची सूचियां। इसलिए, यदि उपयोगकर्ता का उपयोग करने की आधिकारिक तरीका है: /उपयोगकर्ता/thisisausername और आईडी के आधार पर उपयोग करने के लिए, हमारे पास है? /उपयोगकर्ताओं आईडी = 48,573 इसी तरह, हम विभिन्न क्षेत्रों के एक नंबर पर खोज सकते हैं , जैसा कि: /उपयोगकर्ता? firstName = केली प्रेरणा से था: http://jwyseur.blogspot.com/2008/12/uri-design-for-rest.html (देखें "संसाधन खोजना") –

+0

तो आप कैशिंग पर पंसद? मेरे पास आपके जैसा ही समस्या है, लेकिन क्वेरी पैरामीटर के माध्यम से उन्हें समस्या हल नहीं कर सकती है जो एक आरईएसटी एपीआई के प्राथमिक लाभों में से एक को हटा देती है। मुझे आपका पहला बुलेट सुझाव पसंद है ... – HDave

उत्तर

10

आपका पहला विकल्प शायद सबसे अच्छा है।

आईडी के आधार पर उपयोगकर्ताओं के लिए खोज:

/users/id/48573 

कम नाम से उपयोगकर्ताओं के लिए खोज:

/users/name/thisisausername 

अगर वे उस पथ पैरामीटर बाहर छोड़ देते हैं, तो आप हमेशा अपने नए लघु उपयोगकर्ता नाम के प्रारूप का उपयोग कर सकते हैं।

एक अन्य विकल्प है कि मैं काफ़ी देखा है निम्नलिखित की तरह क्वेरी पैरामीटर का उपयोग करने के लिए है:

/users?id=48573 
/users?name=thisisausername 

मैं पहली बार थोड़ा क्लीनर और अधिक पठनीय लग रहा है लगता है।

+0

लघु और बिंदु, सही! –

-3

मैं एक वैकल्पिक प्रत्यय के साथ स्ट्रिंग योग्यता पर विचार करेंगे:

/users/48573/id 

/users/48573/name 

आप प्रत्यय के बिना एक स्ट्रिंग प्राप्त होता है:

/users/48573 

तो आप स्ट्रिंग की जाँच करें और देखें कि क्या वह एक आईडी है या नाम

आप केवल एक वैध पहचान पत्र प्राप्त नहीं बल्कि एक नाम तो यह आईडी के आधार पर एक पुन: प्राप्ति के बराबर बताया गया है:

:

/users/48573/id 

इसे करने के लिए नाम समकक्ष द्वारा एक पुन: प्राप्ति है आप केवल एक नाम वापस तो मिलता है

/users/48573/name 

आप ID या नाम से मान प्राप्त है तो आप एक 300 प्रतिक्रिया त्रुटि लौट सकते हैं और ग्राहक के लिए दोनों possiblities के लिंक लौट सकते हैं:

/users/48573/id 

/users/48573/name 

विरासत उपभोक्ता डुप्लिकेट आईडी/नाम जोड़े के कभी-कभी मौके को छोड़कर 'जैसा है' काम करना जारी रखते हैं, जहां उन्हें नई 300 प्रतिक्रिया त्रुटि प्राप्त होती है।

+7

यह बिल्कुल आरएसटी नहीं है। यह सिर्फ आरपीसी है। – aehlke

-3

यदि आपका कोई मुद्दा है तो आपका एपीआई रीस्टफुल नहीं है। quote रॉय फील्डिंग:

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

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

+1

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

28

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

व्यक्तिगत रूप से, मैं पथ सेगमेंट उपसर्ग "=" द्वारा सीमांकित, जैसे "नाम =" या उपयोग करने की योजना "ईमेल =":

user/123456 
user/name=john.doe 
user/[email protected] 

यह कार्यात्मक रूप पथ सेगमेंट जोड़ने के समकक्ष है (उदाहरण के लिए " उपयोगकर्ता/नाम/john.doe "), लेकिन मुझे लगता है जैसे यह वैचारिक मॉडल के लिए अधिक बारीकी से नक्शा बनाता है। बेशक, यह एक महत्वहीन विवरण है, क्योंकि रीस्टफुल एपीआई को वैसे भी एक निश्चित यूआरआई संरचना निर्दिष्ट नहीं करनी चाहिए।

क्वेरी पैरामीटर का उपयोग नहीं भी अनुमति देता उप-संसाधनों स्वाभाविक रूप से पहुँचा जा रहे हैं:

user/name=john.doe/inbox/df87bhJXrg63 

फ़्रेमवर्क जावा के JAX-रुपये की तरह उपयोग करने का समर्थन जो कुछ सीमांकक आप चाहते हैं:

@GET 
@Path("user/{id}") 
User getUser(@PathParam("id") UUID id); 

@GET 
@Path("user/name={name}") 
User getUserByName(@PathParam("name") String name); 

@GET 
@Path("user/email={email}") 
User getUserByEmail(@PathParam("email") String email); 
+2

यह एक दिलचस्प दृष्टिकोण है जिसे मैंने पहले नहीं देखा है। यह समस्या को अच्छी तरह से हल करता है, लेकिन मैं इस तथ्य को पिछले नहीं समझ सकता कि क्वेरी पैरामीटर के बाहर बराबर चिह्न देखने से यह भ्रम पैदा करेगा ... – HDave

+4

प्लस, यह बहुत ही आरामदायक नहीं है। क्या, बिल्कुल, संग्रह नाम = john.doe है? मेरे लिए यह एक मैट्रिक्स पैरामीटर होना चाहिए: उपयोगकर्ता; नाम = john.doe/inbox/df87 ... http://blog.2partsmagic.com/restful-uri-design/ – Maladon

+0

@ मालाडॉन मुझे लगता है कि आप हैं बिंदु गुम है। 'name = john.doe' संग्रह नहीं होना चाहिए, क्योंकि 'name' एक अद्वितीय पहचानकर्ता है। हम बिल्कुल एक वस्तु या त्रुटि की तलाश में हैं। 'उपयोगकर्ता; नाम = john.doe' एक खोज की तरह दिखता है। मैं उम्मीद करता हूं कि यह वही प्रतिनिधित्व 'उपयोगकर्ता' के रूप में वापस कर देगा, जो एक संग्रह है। –

0

काफी एक पुराने सवाल लेकिन मेरे पास वही था और फिननाली समाधान मिला: अपने पथ परम में regex का उपयोग करें।

यहाँ कैसे मुझे लगता है कि उपयोग के मामले

@GET 
@Path("/{id : \\d+}") 
@Produces(APPLICATION_JSON) 
public Response getById(@PathParam("id") long id) { 
<<your code>> 
} 

@GET 
@Path("/{name}") 
@Produces(APPLICATION_JSON) 
public Response getByName(@PathParam("name") String name) { 
<<your code>> 
} 
+1

क्या होगा यदि उपयोगकर्ता का नाम संख्यात्मक है? यदि कोई उपयोगकर्ता अपना नाम स्वतंत्र रूप से चुन सकता है और केवल एक संख्या का उपयोग करने का निर्णय लेता है तो आपका दृष्टिकोण विफल हो जाता है। –

+0

यह विफल रहता है या नहीं। आपको सृजन (POST) अनुरोध पर नियंत्रण करना है और संख्यात्मक नाम से इनकार कर सकते हैं। – Javathought

+0

@@ POST सार्वजनिक प्रतिक्रिया बनाएं (@ वैध उपयोगकर्ता उपयोगकर्ता) और बीन सत्यापन के साथ अपने मॉडल को एनोटेट करें। उदाहरण: पूंजीकृत पत्र के साथ शुरू होना चाहिए, 50 चार अधिकतम @@ पैटर्न (regexp = "[AZ] [a-zA-Z_0-9-] {0,49}", संदेश = "अमान्य नाम") निजी स्ट्रिंग नाम; – Javathought

संबंधित मुद्दे