7

Let's say I have an app to manage sporting teams. Potential users have a role of 'coach', 'player', and 'fan'. In many cases they will have to make similar api calls to retrieve info like this:

/api/v1/players    (retrieve all players on their current team)
/api/v1/events     (retrieve all events for their current team)

In other cases roles might have certain features only available to them, like this:

/api/v1/opposing_players/:opposing_player_id  (retrieve scouting info about an opposing player, not available to fans)

My question boils down to... Should I explicitly break out the apis with a prefix for each role? Or should the API only have one base url?

/api/v1/coaches/events
/api/v1/fans/events
/api/v1/players/events

or

/api/v1/events
  • Are those events different for each type? Is there any related security issue, like giving access only to certain parts of your API? – scriptin Jul 28 '17 at 16:11
  • For the sake of this question let's assume that 'events' in the last example is the same, but the roles might dictate which events are returned. For your second question, I'd like to hear from people who have had to make this trade-off as part of the answer. Is the overhead of maintaining three separate apis worth being able to move authorization/security upstream? Or should I just bite the bullet and ensure the single api endpoint behaves well and securely for all role types at the request level? – Msencenb Jul 28 '17 at 16:16
  • Does your routing framework let you have routes like /api/v1/{role:string}/events where role is a parameter to the controller function? I have done lots of stuff where parts of the URL are actually parameters that get used in what ever function i am running. – RubberChickenLeader Jul 28 '17 at 16:22
  • @WindRaven I want a higher level perspective. Let's ignore what I can do, as the framework can be made to do anything. How does the tradeoff of separate apis vs a single api that uses role based authorization under the hood play out initially and at scale? Load balancing, technical complexity, maintenance overhead, etc. – Msencenb Jul 28 '17 at 16:43
  • Look at It from the consumer point of view. Which one is easier to consume? Does the consumer need to know the relationship role-event? Why? In which way it represents better your API than the single endpoint? The answer depends on how you want the API to be consumed. – Laiv Jul 28 '17 at 17:56
11

No you shouldn't use level of access as part of the URI.

There is already a standard way to separate API by user access, and that's with authorization. All users should access the same endpoints, and based on the authenticated user's role, or attributes, you can

  • Return 401 Unauthorized - If the user is not authenticated
  • Return 403 Forbidden - If user doesn't have the appropriate role or attributes to access a resource
  • Return different models based on level of access. E.g. coach may be allowed to see each player's birthdate but fans are not allowed. you can show/hide attributes of models based on access.

If you did use a separate API scheme for each role, here are some drawbacks:

  • How do you represent API that are the same for all roles?
  • Must duplicate a lot of routes when a new role is added (e.g. system admin role, or division manager)
  • Changing the name of a role will break the API?
  • Unintuitive - if I'm a coach but I want to access player data, I might think I should access /api/v1/players but really I need to access /api/v1/coaches/players or something
  • How do you represent clients that are players and fans? I.e. multiple roles
  • How do you support allowing unauthenticated clients? I.e. no roles
  • Redundant data - you have to check each user is authorized to access a resource, but now you must also check that the user's role matches the URI . You have to handle the edge case of when the user's role doesn't match the URI role.
  • Changing authorization is an interface-breaking change. Say a coach retires and becomes a fan. They must now change all the endpoints that they used to access.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.