REST API ตามบทบาทหรือไม่


27

ฉันกำลังสร้าง REST API ซึ่งผู้ใช้หลายคนที่มีบทบาทที่แตกต่างกันจะสามารถเข้าถึงทรัพยากรที่มีอยู่

เพื่อให้ขอบเขตง่ายขึ้นขอโดเมน "นักเรียน / ครู / ชั้นเรียน":

GET /students เป็นทรัพยากรที่จะเข้าถึง

ผู้ใช้อาจมีบทบาทเช่นนักเรียนและ / หรืออาจารย์

นักเรียนจะสามารถเข้าถึงนักเรียนของชั้นเรียนของพวกเขาเท่านั้น ครูจะสามารถเข้าถึงนักเรียนของชั้นเรียนที่พวกเขาสอน การใช้งานบางอย่างอาจเป็นนักเรียนและสอนชั้นเรียนอื่น ๆ ด้วย พวกเขาจะต้องสามารถเข้าถึงนักเรียนของชั้นเรียนของพวกเขาและนักเรียนของชั้นเรียนที่พวกเขาสอน

นึกคิดฉันต้องการที่จะใช้สิ่งนี้เป็นสองฟังก์ชั่น - หนึ่งต่อบทบาทและจากนั้น "สหภาพ" ถ้าผู้ใช้มีหลายบทบาท

คำถามของฉันคือฉันควรใช้รูปแบบใดในการดำเนินการนี้

อย่างผิวเผิน

  • ฉันควรแยก API ต่อบทบาทของฉันหรือไม่ GET /teacher/studentsและGET /student/studentsดูเหมือนจะไม่ถูกต้องสำหรับฉัน
  • เก็บทุกอย่างฉันเป็นแหล่งข้อมูลเดียว (แนะนำ)

ภายใน

ควรนำไปใช้ภายในอย่างไร

  • ทุกวิธีควรเริ่มต้นด้วยสวิตช์ขนาดใหญ่ / ต่อบทบาทหรือไม่
  • ฉันควรใช้ที่เก็บต่อบทบาทหรือไม่
  • มีรูปแบบการออกแบบที่จะช่วยฉันในการบรรลุเป้าหมายนี้หรือไม่?

ตามความเห็นด้านข้าง: ฉันใช้ASP.NET Web APIและEntity Framework 6แต่จริงๆแล้วมันไม่สำคัญสำหรับการนำแนวคิดไปใช้


3
"นี่เป็นคำถามที่ดีฉันอยากรู้ว่าคุณมีวิธีแก้ปัญหานี้หรือไม่เพราะฉันพยายามทำสิ่งที่คล้ายกันสิ่งที่ฉันคิดว่ามันควรจะเป็น: อันดับแรกเราจะใช้ API ที่ส่งคืนข้อมูลทั้งหมดที่จำเป็น จากนั้นลูกค้าแต่ละรายจะไม่เชื่อมต่อโดยตรงกับ api แต่ไปยังพร็อกซีที่จะรับผิดชอบในการกรองข้อมูลตามบทบาทจากผู้ใช้นั้น "
Cleiton

คำตอบ:


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 ที่มีเงื่อนไข "OR" สำหรับแต่ละบทบาทที่ผู้ใช้มีสิทธิ์เข้าถึง หากไม่มีการกำหนดบทบาทให้กับผู้ใช้ฉันเพียงแค่คืนค่า Enumarable.Empty () the the caller
Casper Jensen

0

ค้นหาปากกาและกระดาษแล้วเริ่มสร้างแบบจำลองระบบของคุณ

คุณจะพบว่าคุณอาจต้องการนิติบุคคลที่ชื่อ PERSON เนื่องจากทั้งนักเรียนและครู "เป็น" บุคคล "คุณสามารถสร้างเอนทิตีนามธรรมที่เรียกว่าบุคคลที่มีคุณสมบัติทั่วไปเช่นชื่อจริงนามสกุล ฯลฯ อาจารย์ -> is-a -> บุคคล ตอนนี้คุณสามารถลองค้นหาคุณลักษณะสำหรับครูที่ไม่ได้ใช้กับนักเรียน เช่นอาจารย์สอนสอนเกี่ยวกับวิชาหนึ่งเรื่องหรือมากกว่านั้น

การบังคับใช้การรักษาความปลอดภัยถือว่าเป็นลักษณะที่ไม่สามารถใช้งานได้ในแอปพลิเคชันของคุณ มันเป็นข้อกังวลข้ามที่ควรจัดการนอก "ตรรกะทางธุรกิจ" ของคุณ @Robert Munn ชี้ให้เห็นว่าบทบาททั้งหมดควรได้รับการบำรุงรักษาในที่เดียว การใช้บทบาทเพื่อ จำกัด การเข้าถึงฟังก์ชันบางอย่างนั้นค่อนข้างหยาบและแนวคิดนี้เรียกว่าการควบคุมการเข้าถึงตามบทบาท (RBAC)

ในการตรวจสอบว่าครูควรได้รับอนุญาตให้ดูเกรดนักเรียนหรือไม่ควรแสดงในรูปแบบโดเมนของคุณ สมมติว่าครูมีชั้นเรียนเกี่ยวกับการเขียนโปรแกรมวิชา คุณอาจจะแสดงในแบบจำลองของคุณว่านักเรียนเข้าเรียนในวิชาที่แตกต่างกัน นี่คือจุดที่แอปพลิเคชัน / ตรรกะทางธุรกิจเริ่มทำงานนี่คือตรรกะที่คุณสามารถตรวจสอบได้โดยใช้การพัฒนาที่ขับเคลื่อนด้วยการทดสอบ

คุณควรแบ่งทรัพยากรของคุณเพื่อให้แอปพลิเคชันของคุณสามารถทดสอบและแยกส่วนได้

อย่างไรก็ตามวิธีที่ดีที่สุดที่จะแสดงสิ่งที่ฉันหมายถึงคือการแสดงด้วยรหัส :) นี่คือหน้า GitHub: https://github.com/thomasandersen77/role-based-rest-api

โชคดี :)


3
ลิงก์ของคุณไปแล้ว ...
Cleiton
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.