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