Role-based REST API?

I’m building a REST API for which several users with different roles will have access to the resources it contains.

To keep the scope simple let’s take the “student/teacher/class” domain:

GET /students is the resource to access.

Users might have roles like Student and/or Teacher

Students will only have access to students of their classes. Teachers will have access to students of the classes they teach. Some uses may be a student AND teach other classes too. They must have access to the students of their classes AND the students of the classes they teach.

Ideally I want to implement this as two functions – one per role and then “union” if a user have multiple roles.

My question is: Which pattern should I use for implementing this?

Externally

  • Should I split up my API per role? GET /teacher/students and GET /student/students It doesn’t seems right to me.
  • Keep it all I’m one resource (preferred)

Internally

How should it be implemented internally?

  • Should every method start with a BIG switch/if per role?
  • Should I implement a repository per role?
  • Is there a design pattern that will help me in achieving this?

As a side comment: I’m using ASP.NET Web API and Entity Framework 6, but it really doesn’t matter for the conceptual implementation.

1

You should architect the API around resources, not around roles, e.g.:

/rest/students

should be accessible to anyone with a role that allows them to see students.

Internally, you are implementing role-based security. How you go about that depends on the details of your application, but let’s say you have a role table, each person has one or more roles, and those roles determine what each person can access. You have already stated the rules for accessing students:

  • students can access students in the classes they take
  • teachers can access students in the the classes they teach

So when a person calls:

/rest/students

you call a method that accesses students, passing in the role of the person. Here is some pseudo code:

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

and in that method, you could get the students for each role with separate calls, e.g.:

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
  }
}

That’s a very rough idea for what you could do and isn’t necessarily going to fit your specific needs, but it should give you a sense of the pieces involved. If you want to return the classes with each student listed, this is a good approach. If you just want the students, you could extract them from each class and merge them into a collection of students.

No, you should not have a separate repository per role. All the role does is determine how you get the data, and maybe what you can do with the data (e.g. Teachers can enter Student grades). The data itself is the same.

As for patterns, this approach is using Factory Pattern to abstract away the service that gets data based on role. It may or may not be appropriate to have separate services by role. I like this approach because it minimizes the amount of code at each stage of the program and makes it more readable than a switch or if block.

1

Find a pen and a paper and start modelling your system.

You will find that you probably need a domain entity called PERSON. Since both STUDENTS and TEACHER “is-a” PERSON, you could create an abstract entity called PERSON with generic attributes like firstname, lastname, etc. A TEACHER -> is-a -> Person. Now you can try to find characteristics for a TEACHER that doesn’t apply to STUDENTS; e.g. A TEACHER teaches CLASS(es) regarding one or more SUBJECT(s).

Enforcing security is considered a non-functional aspect of your application. It is a cross-cutting concern that should be handled outside of your “business logic”. As @Robert Munn points out, the ROLE(s) should all be maintained in one place. Using roles to limit access to certain functions is rather coarse-grained, and the concept is called role-based access control (RBAC).

To verify whether or not a teacher should be allowed to see a students grades, should to be expressed in your domain model. Say a teacher has a class on the subject programming. You would probably express in your model that students attends classes for different subjects. This is where the application/business logic kicks in. This is logic that you can verify using test-driven development.

You should split your resources to make your application testable and modular.

Anyway, the best way to really show what I mean is to show it with code 🙂 Here is a GitHub page: https://github.com/thomasandersen77/role-based-rest-api

Good luck 🙂

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa

Role-based REST API?

I’m building a REST API for which several users with different roles will have access to the resources it contains.

To keep the scope simple let’s take the “student/teacher/class” domain:

GET /students is the resource to access.

Users might have roles like Student and/or Teacher

Students will only have access to students of their classes. Teachers will have access to students of the classes they teach. Some uses may be a student AND teach other classes too. They must have access to the students of their classes AND the students of the classes they teach.

Ideally I want to implement this as two functions – one per role and then “union” if a user have multiple roles.

My question is: Which pattern should I use for implementing this?

Externally

  • Should I split up my API per role? GET /teacher/students and GET /student/students It doesn’t seems right to me.
  • Keep it all I’m one resource (preferred)

Internally

How should it be implemented internally?

  • Should every method start with a BIG switch/if per role?
  • Should I implement a repository per role?
  • Is there a design pattern that will help me in achieving this?

As a side comment: I’m using ASP.NET Web API and Entity Framework 6, but it really doesn’t matter for the conceptual implementation.

1

You should architect the API around resources, not around roles, e.g.:

/rest/students

should be accessible to anyone with a role that allows them to see students.

Internally, you are implementing role-based security. How you go about that depends on the details of your application, but let’s say you have a role table, each person has one or more roles, and those roles determine what each person can access. You have already stated the rules for accessing students:

  • students can access students in the classes they take
  • teachers can access students in the the classes they teach

So when a person calls:

/rest/students

you call a method that accesses students, passing in the role of the person. Here is some pseudo code:

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

and in that method, you could get the students for each role with separate calls, e.g.:

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
  }
}

That’s a very rough idea for what you could do and isn’t necessarily going to fit your specific needs, but it should give you a sense of the pieces involved. If you want to return the classes with each student listed, this is a good approach. If you just want the students, you could extract them from each class and merge them into a collection of students.

No, you should not have a separate repository per role. All the role does is determine how you get the data, and maybe what you can do with the data (e.g. Teachers can enter Student grades). The data itself is the same.

As for patterns, this approach is using Factory Pattern to abstract away the service that gets data based on role. It may or may not be appropriate to have separate services by role. I like this approach because it minimizes the amount of code at each stage of the program and makes it more readable than a switch or if block.

1

Find a pen and a paper and start modelling your system.

You will find that you probably need a domain entity called PERSON. Since both STUDENTS and TEACHER “is-a” PERSON, you could create an abstract entity called PERSON with generic attributes like firstname, lastname, etc. A TEACHER -> is-a -> Person. Now you can try to find characteristics for a TEACHER that doesn’t apply to STUDENTS; e.g. A TEACHER teaches CLASS(es) regarding one or more SUBJECT(s).

Enforcing security is considered a non-functional aspect of your application. It is a cross-cutting concern that should be handled outside of your “business logic”. As @Robert Munn points out, the ROLE(s) should all be maintained in one place. Using roles to limit access to certain functions is rather coarse-grained, and the concept is called role-based access control (RBAC).

To verify whether or not a teacher should be allowed to see a students grades, should to be expressed in your domain model. Say a teacher has a class on the subject programming. You would probably express in your model that students attends classes for different subjects. This is where the application/business logic kicks in. This is logic that you can verify using test-driven development.

You should split your resources to make your application testable and modular.

Anyway, the best way to really show what I mean is to show it with code 🙂 Here is a GitHub page: https://github.com/thomasandersen77/role-based-rest-api

Good luck 🙂

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật