python - RESTfully routing an API based on user roles -
i developing api using flask-restful, , application has 3 roles.
- site_admin
 - department_admin
 - 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
Post a Comment