संसाधनों को डिजाइन / लॉगिन या रजिस्टर करें?


122

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

GET  /logout   // destroys session and redirects to /
GET  /login    // gets the webpage that has the login form
POST /login    // authenticates credentials against database and either redirects home with a new session or redirects back to /login
GET  /register // gets the webpage that has the registration form
POST /register // records the entered information into database as a new /user/xxx
GET  /user/xxx // gets and renders current user data in a profile view
POST /user/xxx // updates new information about user

मुझे लग रहा है कि मैं एसओ और गूगल पर घूमने के बाद यहां बहुत गलत कर रहा हूं।

के साथ शुरू /logout, शायद जब से मैं वास्तव में GETकुछ भी नहीं है - यह सत्र को नष्ट करने, और फिर पुनर्निर्देशित POSTकरने के अनुरोध के लिए अधिक उपयुक्त हो सकता है । और कार्यकाल बना रहना चाहिए ?/logoutGET/logout

क्या बारे में /loginऔर /register। मैं बदल सकता /registerथा, /registrationलेकिन यह मेरी सेवा मौलिक रूप से कैसे काम करता है - अगर इसमें गहन मुद्दे हैं, तो यह बदल नहीं सकता ।

मैं अब नोटिस करता हूं कि मैं एक /userसंसाधन को उजागर नहीं करता हूं । शायद यह किसी भी तरह से उपयोग किया जा सकता है। उदाहरण के लिए, उपयोगकर्ता को लें myUser:

foo.com/user/myUser

या

foo.com/user

अंतिम उपयोगकर्ता को URI में अतिरिक्त वर्बोसिटी की आवश्यकता नहीं है। हालाँकि, कौन सा अधिक नेत्रहीन है?

मैंने इस REST व्यवसाय के बारे में SO पर कुछ अन्य प्रश्नों पर ध्यान दिया है, लेकिन यदि संभव हो तो मैंने यहाँ जो कुछ रखा है, उस पर कुछ मार्गदर्शन की सराहना करता हूँ।

धन्यवाद!

अपडेट करें:

मैं कुछ राय भी चाहूंगा:

/user/1

बनाम

/user/myUserName

जवाबों:


63

एक बात विशेष रूप से नहीं के रूप में बाहर चिपक जाती है: लॉग आउट करने के लिए GET अनुरोध का उपयोग।

( http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Safe_meths से )

कुछ तरीकों (उदाहरण के लिए, HEAD, GET, OPTIONS और TRACE) को सुरक्षित के रूप में परिभाषित किया गया है, जिसका अर्थ है कि वे केवल सूचना पुनर्प्राप्ति के लिए अभिप्रेत हैं और सर्वर की स्थिति को नहीं बदलना चाहिए। दूसरे शब्दों में, उनके साइड इफेक्ट्स नहीं होने चाहिए, अपेक्षाकृत हानिरहित प्रभावों से परे, जैसे लॉगिंग, कैशिंग, बैनर विज्ञापनों की सेवा या एक वेब काउंटर को बढ़ाना। [...]

[... एच] और [जीईटी अनुरोधों का] सर्वर द्वारा तकनीकी रूप से किसी भी तरह से सीमित नहीं है। इसलिए, लापरवाह या जानबूझकर प्रोग्रामिंग सर्वर पर गैर-तुच्छ परिवर्तन का कारण बन सकती है। यह हतोत्साहित किया जाता है, क्योंकि यह वेब कैशिंग, खोज इंजन और अन्य स्वचालित एजेंटों के लिए समस्याएं पैदा कर सकता है [...]

लॉग आउट करने और रीडायरेक्ट करने के लिए, आप अपने लॉगआउट के लिए एक पोस्ट कर सकते हैं URI पोस्ट-लॉगआउट पेज पर पुनर्निर्देशन के लिए 303 प्रतिसाद दें।

http://en.wikipedia.org/wiki/Post/Redirect/Get

http://en.wikipedia.org/wiki/HTTP_303

URL डिज़ाइन चिंताओं को संबोधित करने के लिए संपादित करें:

"मैं अपने संसाधनों को कैसे डिजाइन करूं?" मेरे लिए एक महत्वपूर्ण प्रश्न है; "मैं अपने URL कैसे डिज़ाइन करूं?" दो क्षेत्रों में एक विचार है:

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

यदि JRandomUserआवश्यकताओं अपने ही प्रोफाइल को देखो और आप URL से खूबसूरत होना चाहता हूँ करने के लिए foo.com/user/JRandomUserया foo.com/user/(JRandom's numeric user id here), तो आप सिर्फ अपने स्वयं के बारे में जानकारी को देखने के लिए एक उपयोगकर्ता के लिए एक अलग यूआरएल बना सकता है:

GET foo.com/profile /*examines cookies to figure out who 
                     * is logged in (SomeUser) and then 
                     * displays the same response as a
                     * GET to foo.com/users/SomeUser.
                     */

मैं इस विषय पर ज्ञान की तुलना में बहुत आसानी से अज्ञानता का दावा करूंगा, लेकिन यहां कुछ संसाधन डिजाइन विचार हैं:

  1. उपभोक्ता: कौन से संसाधन XHR के माध्यम से लोड किए गए या किसी अन्य प्रकार के क्लाइंट द्वारा सीधे ब्राउज़र में देखे जाने हैं?
  2. पहुँच / पहचान: क्या प्रतिक्रिया कुकीज़ या रेफ़रर्स पर निर्भर करती है?

1
शानदार जवाब, धन्यवाद! अगर मैं आपके अलग-अलग URL सुझाव ( GET foo.com/profile/) को लागू करने जा रहा हूं , जैसा कि मोमो ने सुझाया है, तो प्रस्तुति परत? दूसरे शब्दों में, क्या वास्तव में उस GETअनुरोध को वापस करना चाहिए ? एक वेब पेज या कुछ JSON?
क्यूकॉम

2
आह, मुझे लगता है कि मैं अब देखता हूं। मोमो के जवाब ने वास्तव में चीजों को साफ कर दिया। तो एक RESTful API करने के लिए कई प्लेटफार्मों अनुमति देने के लिए निर्माण किया है GET, POST, PUT, और DELETEसंसाधनों। एक वेबसाइट एपीआई को एक्सेस करने के लिए सिर्फ एक अन्य प्लेटफॉर्म है। दूसरे शब्दों में, वेबसाइट URL डिज़ाइन RESTful API डिज़ाइन से पूरी तरह अलग है। कृपया मुझे बताएं कि क्या मैं अभी भी गलत हूं।
Qcom

हां, अपने REST API को URL और आपकी वेबसाइट के सेट को एक अलग सेट बनाएं। फिर आपके वेबसाइट के URL को आपको उपयुक्त HTML + Javascript वापस देनी चाहिए ताकि पृष्ठ क्लाइंट के रूप में कार्य करने के लिए आपके API URL में XmlHttpRequests को उपयुक्त बना दे।
एलीसबेन

129

RESTful का उपयोग URL बनाने के लिए एक दिशानिर्देश के रूप में किया जा सकता है, और आप सत्र और उपयोगकर्ता संसाधन बना सकते हैं :

  • GET /session/new उस वेबपेज को प्राप्त करता है जिसमें लॉगिन फ़ॉर्म है
  • POST /session डेटाबेस के खिलाफ प्रमाणिकता को प्रमाणित करता है
  • DELETE /session सत्र को नष्ट कर देता है और / पर पुनर्निर्देशित करता है
  • GET /users/new उस वेबपेज को प्राप्त करता है जिसमें पंजीकरण फॉर्म है
  • POST /users डेटाबेस में दर्ज जानकारी को नए / उपयोगकर्ता / xxx के रूप में दर्ज करता है
  • GET /users/xxx // एक प्रोफ़ाइल दृश्य में वर्तमान उपयोगकर्ता डेटा प्राप्त करता है और प्रदान करता है
  • POST /users/xxx // उपयोगकर्ता के बारे में नई जानकारी अपडेट करता है

ये बहुवचन या एकवचन हो सकते हैं (मुझे यकीन नहीं है कि कौन सा सही है)। मैंने आमतौर पर /usersएक उपयोगकर्ता इंडेक्स पेज के लिए उपयोग किया है (जैसा कि अपेक्षित है), और /sessionsयह देखने के लिए कि कौन लॉग इन है (उम्मीद के मुताबिक)।

एक नंबर ( /users/43बनाम /users/joe) के बजाय URL में नाम का उपयोग करना आमतौर पर उपयोगकर्ताओं या खोज इंजनों के लिए अधिक अनुकूल होने की इच्छा से प्रेरित होता है, न कि किसी तकनीकी आवश्यकताओं के आधार पर। या तो ठीक है, लेकिन मैं आपको सुसंगत सलाह दूंगा।

मुझे लगता है कि यदि आप रजिस्टर / लॉगिन / लॉगआउट के साथ जाते हैं या sign(in|up|out), यह बाकी शब्दावली के साथ भी काम नहीं करता है।


6
बहुत बढ़िया! मुझे पसंद है कि आप उन संसाधनों की संज्ञा कैसे देते हैं; यह बहुत साफ है। हालांकि, मैंने जो सुना है, उससे नॉन रेस्टफुल के /newलिए GET /session/अपील नहीं की जा रही है? मैंने सुना है कि क्रियाओं विशेष प्रकार से HTTP क्रियायें (करने के लिए छोड़ दिया जाता है GET, POST, आदि)।
Qcom

2
@ नया कोई क्रिया नहीं है। इस मामले में यह सत्र का एक उप-स्रोत है।
कुगेल

DELETE / सत्र में किस सत्र को कैसे हटाया जाए? कर्ल न तो कुकीज़ भेजते हैं और न ही DELETE अनुरोध में कोई पैरामेस भेजते हैं। मुझे लगता है - सिर्फ DELETE / session / sessionId का उपयोग करने के लिए? एक और सवाल यह है कि POST / सत्र में सत्र आईडी को कैसे वापस किया जाए और किस प्रारूप में है।
तवरोह

9
बाकी वास्तव में खुद को दुखी करने और उन चीजों पर समय बर्बाद करने का एक तरीका है जो बिल्कुल भी मायने नहीं रखते हैं।
जियान चेन

6
व्यक्तिगत रूप से मुझे उन मार्गों के होने का विचार पसंद नहीं है जो प्रपत्र (/ नया) लौटाते हैं। यह दृश्य और व्यावसायिक तर्क के बीच अलगाव को तोड़ता है। ठा ने कहा, / नए मार्गों के बिना सुझाया गया एक नज़र एकदम सही है।
'15

60

सत्र रेस्टफुल नहीं हैं

  • हाँ मैं जानता हूँ। यह आमतौर पर OAuth के साथ किया जा रहा है, लेकिन वास्तव में सत्र रेस्टफुल नहीं हैं। आपके पास प्राथमिक रूप से एक / लॉगिन / लॉगआउट संसाधन नहीं होना चाहिए क्योंकि आपके पास सत्र नहीं होने चाहिए।

  • यदि आपका यह करने जा रहा है, तो इसे RESTful बनाएं। संसाधन संज्ञा हैं और / लॉगिन और / लॉगआउट संज्ञा नहीं हैं। मैं / सत्र के साथ जाऊंगा। यह सृजन और विलोपन को अधिक प्राकृतिक क्रिया बनाता है।

  • सत्रों के लिए POST बनाम GET आसान है। यदि आप उपयोगकर्ता / पासवर्ड को चर के रूप में भेज रहे हैं, तो मैं POST का उपयोग करूंगा क्योंकि मैं URI के हिस्से के रूप में भेजा गया पासवर्ड नहीं रखना चाहता। यह लॉग में दिखाई देगा और संभवतः तार पर उजागर किया जाएगा। आप जीईटी आर्ग की सीमाओं पर सॉफ़्टवेयर विफल होने का जोखिम भी चलाते हैं।

  • मैं आम तौर पर REST सेवाओं के साथ मूल प्रमाणीकरण या कोई प्रामाणिक का उपयोग नहीं करता हूं।

उपयोगकर्ता बनाना

  • यह एक संसाधन है, इसलिए आपको पंजीकरण / पंजीकरण की आवश्यकता नहीं होनी चाहिए।

    • POST / उपयोगकर्ता - एक उपयोगकर्ता बनाता है यदि अनुरोधकर्ता आईडी निर्दिष्ट नहीं कर सकता है
    • PUT / user / xxx - मान लें कि आप पहले से आईडी जानते हैं, एक उपयोगकर्ता बनाएं या अपडेट करें
    • GET / उपयोगकर्ता - x उपयोगकर्ता आईडी को सूचीबद्ध करता है
    • GET / user / xxx - आईडी xxx के साथ उपयोगकर्ता का विवरण प्राप्त करता है
    • DELETE / उपयोगकर्ता / xxx - आईडी xxx वाले उपयोगकर्ता को हटा दें
  • किस तरह की आईडी का इस्तेमाल करना है यह एक कठिन सवाल है। आपको अद्वितीयता लागू करने के बारे में सोचना होगा, पुरानी आईडी के पुन: उपयोग के बारे में जो DELETEd थे। उदाहरण के लिए, यदि आप आईडी को पुनर्नवीनीकरण करने जा रहे हैं (यदि संभव हो तो)। बैकएंड आवश्यकताओं को कम करने के लिए आप बाहरी / आंतरिक आईडी रूपांतरण के लिए एक लुकअप कर सकते हैं।


6
यह सबसे अच्छा जवाब है। / लॉगिन और लॉगआउट संसाधन नहीं हैं और REST के विचार को तोड़ते हैं।
wle8300

5
प्रमाणीकरण! = सत्र
डाइटबुद्ध १३'१ S

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

दरअसल, / लॉगइन और / लॉगआउट संज्ञाएं हैं। मुझे लगता है कि आप / log_in और / log_out के बारे में सोच रहे हैं।
TiggerToo

21

मैं अपने अनुभव से केवल अपने ग्राहकों के लिए विभिन्न REST वेब सेवाओं को एकीकृत करने के लिए जा रहा हूं, चाहे वह मोबाइल एप्लिकेशन के लिए या सर्वर से सर्वर संचार के लिए और साथ ही दूसरों के लिए REST API के निर्माण के लिए उपयोग किया जाए। यहाँ कुछ अवलोकन हैं जो मैंने अन्य लोगों के REST API के साथ-साथ उन लोगों से लिए हैं जिन्हें हमने स्वयं बनाया है:

  • जब हम एपीआई कहते हैं, तो यह आम तौर पर प्रोग्रामिंग इंटरफेस के सेट को संदर्भित करता है और प्रस्तुति परत को आवश्यक नहीं करता है। REST भी डेटा केंद्रित है और प्रस्तुतिकरण संचालित नहीं है। कहा कि JEST या XML के रूप में अधिकांश REST रिटर्न डेटा और शायद ही कोई विशिष्ट प्रस्तुति परत लौटाता है। इस विशेषता (रिटर्निंग डेटा और डायरेक्ट वेबपेज नहीं) ने REST को मल्टी-चैनल डिलीवरी करने की क्षमता दी। इसका मतलब है कि एक ही वेब सेवा को HTML, iOS, Android में प्रस्तुत किया जा सकता है या यहां तक ​​कि सर्वर से सर्वर संयोजन के रूप में भी उपयोग किया जा सकता है।
  • HTML और REST दोनों को एक URL के रूप में संयोजित करना बहुत दुर्लभ है। डिफ़ॉल्ट रूप से REST सेवाएँ हैं और प्रस्तुति परत नहीं होने के कारण विचार हैं। यह उन लोगों के लिए काम है, जो उन सेवाओं से डेटा को प्रस्तुत करने के लिए webservices का उपभोग करते हैं, जो वे चाहते हैं के अनुसार कॉल करते हैं। उस बिंदु के नीचे आपका URL अधिकांश REST आधारित डिज़ाइन के अनुरूप नहीं है, जो मैंने अब तक सामना किया है (न ही मानकों जैसे कि जो फेसबुक या ट्विटर से आ रहे हैं)
GET / register // में वह वेबपेज मिलता है जिसमें पंजीकरण फॉर्म होता है
  • पिछले बिंदु से जारी रखते हुए, यह भी असामान्य है (और मैंने सामना नहीं किया है) REST आधारित सेवा के लिए पुनर्निर्देशन जैसे कि नीचे दिए गए सुझाव हैं:
GET / लॉगआउट // सत्र को नष्ट कर देता है और / पर रीडायरेक्ट करता है
पोस्ट / लॉगिन // डेटाबेस के खिलाफ क्रेडेंशियल्स को प्रमाणित करता है और या तो एक नए सत्र के साथ घर को पुनर्निर्देशित करता है या वापस / लॉगिन पर रीडायरेक्ट करता है
 

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

  • REST में, URL की गई कार्रवाइयों को दर्शाता है। उस कारण से, हमें यथासंभव अस्पष्टता को दूर करना चाहिए। हालांकि यह आपके मामले में GET और POST दोनों के लिए वैध है, जिसमें एक ही पथ (जैसे / रजिस्टर) है जो अलग-अलग कार्रवाई करते हैं, इस तरह के डिज़ाइन प्रदान की गई सेवाओं में अस्पष्टता का परिचय देते हैं और आपकी सेवाओं के उपभोक्ता को भ्रमित कर सकते हैं। उदाहरण के लिए, आपके द्वारा नीचे दिए गए URL जैसे REST आधारित सेवाओं के लिए आदर्श नहीं हैं
GET / register // में वह वेबपेज मिलता है जिसमें पंजीकरण फॉर्म होता है
पोस्ट / रजिस्टर // डेटाबेस में दर्ज जानकारी को एक नए / उपयोगकर्ता / xxx के रूप में दर्ज करता है

वे कुछ बिंदु हैं जिनसे मैंने निपटा है। मुझे आशा है कि यह आपके लिए कुछ अंतर्दृष्टि प्रदान कर सकता है।

अब आपके REST के क्रियान्वयन के लिए, ये विशिष्ट कार्यान्वयन हैं, जिनका मैंने सामना किया है:

  • गेट / लॉगआउट करें  
    

    बैकएंड में लॉगआउट निष्पादित करें और ऑपरेशन की सफलता / विफलता को दर्शाने के लिए JSON लौटाएं

  • पोस्ट / लॉगिन
    

    बैकएंड पर क्रेडेंशियल सबमिट करें। सफलता / असफलता लौटाओ। यदि सफल होता है, तो सामान्य रूप से यह सत्र टोकन के साथ-साथ प्रोफ़ाइल जानकारी भी लौटाएगा।

  • पोस्ट / रजिस्टर
    

    बैकएंड पर पंजीकरण जमा करें। सफलता / असफलता लौटाओ। यदि सफल, आम तौर पर सफल लॉगिन के रूप में ही व्यवहार किया जाता है या आप एक विशिष्ट सेवा के रूप में पंजीकरण करने का विकल्प चुन सकते हैं

  • GET / उपयोगकर्ता / xxx
    

    उपयोगकर्ता प्रोफ़ाइल प्राप्त करें और उपयोगकर्ता की प्रोफ़ाइल के लिए JSON डेटा प्रारूप लौटाएं

  • POST / उपयोगकर्ता / xxx 
    // नाम दिया गया 
    पोस्ट / अपडेटर / एक्सएक्सएक्स
    

    अद्यतन प्रोफ़ाइल जानकारी को JSON प्रारूप के रूप में पोस्ट करें और बैकएंड में जानकारी को अपडेट करें। कॉलर को सफलता / विफलता लौटाएं


3
हां, यदि आप अपने REST API को HTML आधारित ऐप (जावास्क्रिप्ट और AJAX के माध्यम से) के साथ एकीकृत कर रहे हैं, तो आपको जबरदस्त लाभ होगा क्योंकि JSON को मूल रूप से जावास्क्रिप्ट द्वारा पार्स किया जाता है। Android / Java में, JSON XML की तुलना में पार्स करने के लिए अधिक आसान और सरल है।
मोमो

15
गेट / लॉगआउट खतरनाक है। GET को बेरोजगार होना चाहिए। इसके अलावा ब्राउज़र <a> hrefs को प्रीफ़ैच करना पसंद करते हैं, जो आपको लॉग आउट करेंगे!
कुगेल

4

मेरा मानना ​​है कि यह प्रमाणीकरण के लिए एक उपयोगी दृष्टिकोण है। LogIn के लिए आप उपयोग करें HttpPut। इस HTTP विधि का उपयोग निर्माण के लिए किया जा सकता है जब कुंजी प्रदान की जाती है, और बार-बार कॉल करना बेकार है। लॉगऑफ़ के लिए, आप HttpDeleteविधि के तहत उसी पथ को निर्दिष्ट करते हैं । कोई क्रिया उपयोग नहीं की गई। उचित संग्रह बहुवचन। HTTP तरीके उद्देश्य का समर्थन करते हैं।

[HttpPut]
[Route("sessions/current")]
public IActionResult LogIn(LogInModel model) { ... }

[HttpDelete]
[Route("sessions/current")]
public IActionResult LogOff() { ... }

यदि वांछित है तो आप सक्रिय के लिए वर्तमान स्थानापन्न कर सकते हैं।


1

मैं ट्विटर के समान एक उपयोगकर्ता खाता URL का उपयोग करने की सलाह foo.com/myUserNameदूंगा जहां उपयोगकर्ता का खाता URL कुछ वैसा ही होगा जैसा आप URL के साथ अपने ट्विटर खाते पर प्राप्त कर सकते हैं https://twitter.com/joelbyler

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

संक्षेप में, मेरा सुझाव है कि आप इसे सरल रखें, URL कम यादगार होने चाहिए।


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