भूमिका आधारित बाकी एपीआई?


27

मैं एक REST API का निर्माण कर रहा हूं, जिसके लिए विभिन्न भूमिकाओं वाले कई उपयोगकर्ताओं के पास मौजूद संसाधनों तक पहुंच होगी।

दायरा सरल रखने के लिए आइए "छात्र / शिक्षक / कक्षा" डोमेन लें:

GET /students उपयोग करने के लिए संसाधन है।

उपयोगकर्ता छात्र और / या शिक्षक की भूमिका निभा सकते हैं

छात्रों को केवल उनकी कक्षाओं के छात्रों तक ही पहुंच होगी। शिक्षक उन कक्षाओं के छात्रों तक पहुंच बनाएंगे जो वे पढ़ाते हैं। कुछ उपयोग छात्र हो सकते हैं और अन्य कक्षाएं भी सिखा सकते हैं। उन्हें अपनी कक्षाओं के छात्रों और उन कक्षाओं के छात्रों तक पहुंच होनी चाहिए जो वे पढ़ाते हैं।

आदर्श रूप से मैं इसे दो कार्यों के रूप में लागू करना चाहता हूं - एक प्रति भूमिका और फिर "संघ" यदि उपयोगकर्ता की कई भूमिकाएं हैं।

मेरा प्रश्न है: इसे लागू करने के लिए मुझे किस पैटर्न का उपयोग करना चाहिए?

बाह्य

  • क्या मुझे अपनी भूमिका प्रति एपीआई विभाजित करनी चाहिए? GET /teacher/studentsऔर GET /student/studentsयह मुझे सही नहीं लगता।
  • यह सब रखो मैं एक संसाधन हूँ (पसंदीदा)

के भीतर

इसे आंतरिक रूप से कैसे लागू किया जाना चाहिए?

  • क्या प्रत्येक विधि को BIG स्विच के साथ शुरू होना चाहिए / यदि प्रति भूमिका है?
  • क्या मुझे प्रति भूमिका एक भंडार लागू करना चाहिए?
  • क्या कोई डिज़ाइन पैटर्न है जो मुझे इसे प्राप्त करने में मदद करेगा?

एक साइड कमेंट के रूप में: मैं ASP.NET वेब एपीआई और एंटिटी फ्रेमवर्क 6 का उपयोग कर रहा हूं , लेकिन यह वैचारिक कार्यान्वयन के लिए वास्तव में मायने नहीं रखता है।


3
"यह एक महान सवाल है, मैं जानना चाहूंगा कि क्या आप इसके लिए कोई समाधान लेकर आए हैं, क्योंकि मैं कुछ ऐसा ही करने की कोशिश कर रहा हूं। मुझे लगता है कि यह होना चाहिए: सबसे पहले, हम एक एपी को लागू करेंगे जो सभी डेटा को लौटाता है। , फिर प्रत्येक ग्राहक एपीआई से नहीं बल्कि एक प्रॉक्सी से कनेक्ट होगा जो उस उपयोगकर्ता से भूमिकाओं के डेटा
रिकॉर्डिंग

जवाबों:


11

आपको API को संसाधनों के चारों ओर लगाना चाहिए, भूमिकाओं के आसपास नहीं, जैसे:

/rest/students

किसी को भी ऐसी भूमिका के लिए सुलभ होना चाहिए जो उन्हें छात्रों को देखने की अनुमति देता है।

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

  • छात्र अपने द्वारा ली जाने वाली कक्षाओं में छात्रों तक पहुँच सकते हैं
  • शिक्षक कक्षाओं में छात्रों को पढ़ाते हैं जो वे पढ़ाते हैं

इसलिए जब कोई व्यक्ति फोन करता है:

/rest/students

आप एक ऐसी विधि कहते हैं जो छात्रों की पहुँच में है, जो व्यक्ति की भूमिका में है। यहाँ कुछ छद्म कोड है:

roles = person.roles; //array
students = getStudents( roles );
return students;

और उस पद्धति में, आप छात्रों को प्रत्येक भूमिका के लिए अलग-अलग कॉल कर सकते हैं, जैसे:

factory = getFactory();
classes= [];
students = [];
for( role in roles ){
    service = factory.getService( role );
    // implementation details of how you get classes for student/teacher are hidden in the service
    classes = classes.merge( service.getClasses( person ) );
    // classes[] has class.students[]
    // loop on classes and add each student to students, or send back classes with nested students? depends on use case
  }
}

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

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

पैटर्न के लिए, यह दृष्टिकोण फ़ैक्टरी पैटर्न का उपयोग कर रहा है ताकि भूमिका के आधार पर डेटा प्राप्त करने वाली सेवा को अलग किया जा सके। भूमिका द्वारा अलग-अलग सेवाओं का होना या होना उचित नहीं हो सकता है। मुझे यह दृष्टिकोण पसंद है क्योंकि यह कार्यक्रम के प्रत्येक चरण में कोड की मात्रा को कम करता है और इसे स्विच या यदि ब्लॉक से अधिक पठनीय बनाता है।


1
उत्तर के लिए धन्यवाद। आपने जो कुछ सुझाया था, मैंने उसे पूरा किया। LINQ2SQL (C #) का उपयोग करके मैं क्वेरी को प्रत्येक "भूमिका" में पारित कर सकता हूं और उपयोगकर्ता को मिली प्रत्येक भूमिका के लिए एक आवेदन कर सकता हूं। परिणाम प्रत्येक उपयोगकर्ता के लिए उपयोग की जाने वाली "या" स्थिति के साथ एक sql कथन होगा। यदि कोई भूमिका किसी उपयोगकर्ता को नहीं सौंपी जाती है तो मैं केवल Enumarable.Empty () कॉलर को वापस कर देता हूं।
कैस्पर जेन्सेन

0

एक पेन और एक पेपर ढूंढें और अपने सिस्टम को मॉडलिंग करना शुरू करें।

आप पाएंगे कि आपको संभवतः PERSON नामक एक डोमेन इकाई की आवश्यकता है। चूँकि छात्र और शिक्षक दोनों एक "PERSON" हैं, इसलिए आप PERSON नामक एक अमूर्त इकाई बना सकते हैं जैसे फर्स्टनेम, लास्टनाम, आदि। A TEACHER -> is-a - a - Person। अब आप एक शिक्षक के लिए विशेषताओं को खोजने की कोशिश कर सकते हैं जो छात्रों पर लागू नहीं होते हैं; जैसे एक शिक्षक एक या अधिक SUBJECT (s) के संबंध में कक्षा (तों) पढ़ाता है।

सुरक्षा लागू करना आपके आवेदन का एक गैर-कार्यात्मक पहलू माना जाता है। यह एक क्रॉस-कटिंग चिंता है जिसे आपके "व्यावसायिक तर्क" के बाहर संभाला जाना चाहिए। जैसा कि @Robert Munn बताते हैं, ROLE (s) सभी को एक ही स्थान पर बनाए रखा जाना चाहिए। कुछ कार्यों तक पहुंच को सीमित करने के लिए भूमिकाओं का उपयोग करना मोटे तौर पर दानेदार होता है, और अवधारणा को भूमिका-आधारित अभिगम नियंत्रण (RBAC) कहा जाता है ।

यह सत्यापित करने के लिए कि एक शिक्षक को छात्रों के ग्रेड देखने की अनुमति दी जानी चाहिए या नहीं, आपके डोमेन मॉडल में व्यक्त किया जाना चाहिए। कहते हैं कि शिक्षक के पास विषय प्रोग्रामिंग पर एक कक्षा है। आप शायद अपने मॉडल में व्यक्त करेंगे कि छात्र विभिन्न विषयों के लिए कक्षाओं में भाग लेते हैं। यह वह जगह है जहां एप्लिकेशन / व्यवसाय तर्क अंदर घुसता है। यह तर्क है कि आप परीक्षण-संचालित विकास का उपयोग करके सत्यापित कर सकते हैं।

आपको अपने एप्लिकेशन को परीक्षण योग्य और मॉड्यूलर बनाने के लिए अपने संसाधनों को विभाजित करना चाहिए

वैसे भी, वास्तव में मुझे दिखाने का सबसे अच्छा तरीका कोड के साथ दिखाने का मतलब है :) यहाँ एक GitHub पृष्ठ है: https://github.com/thomasandersen77/role-based-rest-api

सौभाग्य :)


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