python - RESTfully routing an API based on user roles -


i developing api using flask-restful, , application has 3 roles.

  1. site_admin
  2. department_admin
  3. basic

for given resource, json object returned has different set of keys based on each role.

for example, if hit /orders "site_admin", result this:

{   "orders": [     {"id": 1, "user": "foo", "paid": true,  "department": "a", "code": 456},     {"id": 2, "user": "bar", "paid": false, "department": "a", "code": 567},     {"id": 3, "user": "meh", "paid": false, "department": "b", "code": 678}   ] } 

however, if hit /orders "department_admin", result this:

{   "orders": [     {"id": 3, "user": "meh", "paid": false}   ] } 

and if hit /orders "basic" minimal json response this:

{   "orders": [     {"id": 2, "paid": true}   ] } 

what restful way of implementing this?

i can come 3 ways of doing it.

(1) using request arg , filtering on that:

class orders(restful.resource):   def get(self):     if request.args['role'] == 'site_admin':       return admin_json_response()     elif request.args['role'] == 'department_admin':       return dept_admin_json_response()     else:       return basic_json_response()  api.add_resource(orders, '/orders') 

(2) filtering on session object:

class orders(restful.resource):   def get(self):     if session['role'] == 'site_admin':       return admin_json_response()     elif session['role'] == 'department_admin':       return dept_admin_json_response()     else:       return basic_json_response()  api.add_resource(orders, '/orders') 

(3) having different route each role:

class orderssiteadmin(restful.resource):   def get(self):     return admin_json_response() api.add_resource(orderssiteadmin, '/orders_site_admin')  class ordersdeptadmin(restful.resource):   def get(self):     return dept_admin_json_response() api.add_resource(ordersdeptadmin, '/orders_dept_admin')  class ordersbasic(restful.resource):   def get(self):       return basic_json_response() api.add_resource(ordersbasic, '/orders_basic') 

... there consensus on preferred way restfully?

thanks much!

your option #2 violates the "stateless" constraint, use of user sessions not idea in rest api, , instead should require clients provide authentication every request.

let's assume fix #2 , instead of user session have current_user variable, populated during authentication. rewrite example follows:

class orders(restful.resource):   def get(self):     if current_user.role == 'site_admin':       return admin_json_response()     elif current_user.role == 'department_admin':       return dept_admin_json_response()     else:       return basic_json_response()  api.add_resource(orders, '/orders') 

let's @ 3 options 1 one:

  • (1) specifies role in query string, enable user request representation, passing desired role. why put role in query string? assume authenticate users, knowing user know role. seems unnecessary , give validation effort.

  • (3) creates different resources each role. once again, have ensure "basic" user not have access 2 urls apply higher roles, have validation work here.

  • (2) assumes user database stores role of each user, once user authenticated correct representation his/her role returned based on assigned role. is, think, best option, users have no way hack way data not allowed see.

speaking of being restful, @ representations, can improved. consider implementing links other resources instead of providing ids, comply hateoas constraint.


Comments

Popular posts from this blog

ruby on rails - RuntimeError: Circular dependency detected while autoloading constant - ActiveAdmin.register Role -

c++ - OpenMP unpredictable overhead -

javascript - Wordpress slider, not displayed 100% width -