Levels of User Permissions in a RESTful API

httphttp-responseresturl

Let's say I have a company that ranks the cutest cats on the internet.

I offer a resource at /cats/ which provides users with the latest, cutest adorable cats.

Users can either get just the top 3 cats if they haven't paid at all or registered. The top 10 cats if they paid 337 dollars and are logged in, and the top 100 cats if they paid 1337 dollars and are logged in. I have a 'user identifier' when making the request.

In short, consumers of /cats/ get a different number of cats based on their 'user
ranking'
. I do have a user identifier on the consuming end, but I have no explicit representation of the user level on the consuming end. I'd like to inform users they can upgrade their subscription when making the request. That is, I need to distinguish between 3 cats since I only offer 3 cats and 3 cats because that's what the user level allowed.

What is the best practice for distinguishing limiting the resource because the consumer does not have sufficient priviledges and limiting it because that's what the consumer has?

How does the client know if they can upgrade their ranking? That is, they only got a limited resource because they don't have permissions. What is the best practice here?

Note, this is a gross simplification of the actual case. Also, just to clarify – reading is appreciated.


Update:

Here are options we've considered:

  • Storing the user permissions objects once on the client, querying for it only when account login or upgrade is performed.
  • Passing null values in JSON indicating it exists, but an actual nothing was transfered. So 10 cats for a user with 3 cats could be ["Garfield","Sylvester","Puss in Boots",null*7]
  • Passing a resource permission pair {cats:["Whiskers","Fluffy","Socks"],authCount:3}

I'd like to do this right the first time to deliver the cutest cats in the best way possible and we'd and we'd like

Best Answer

I'd say it depends on your audience.

No-dev

If your audience is not a developer's one, I'd go with the following way:

Let's say you return JSON for the sake of the example.

GET /cats HTTP/1.1

{
    "cats": [
        "Can I haz cheeseburger",
        "If it fits, I sits",
        "It's caturday!"
    ],
    "permissions": {
        "level": "free",
        "information": "You have access to 3 cats. Upgrade to ... to get 10 cats!"
    }
}

Or something similar.

It is informative for the user to know what the status of his account is, and it allows you to put whatever information you want, such as a marketing message. The most important point of this way is to give some easy visibility to your users of their current account.

Dev

However, if your audience is purely developers, then I'd say: go with the full HTTP compliant way. To store the metadata, you use HTTP headers.

Here is an example:

GET /cats HTTP/1.1

X-Account: anonymous
X-Account-Possible-Upgrades: 2
X-Account-Limit: 3

Then, provide a clear documentation of what these headers mean. Most developers will go straight for the documentation when they'll see these custom headers, especially if they're seeing a limit. You can go even further and show the link in the headers. Or you can show a link to the pricing page.

X-Account-Doc: http://your/doc

But then again, many developers don't know how HTTP works.

So it's your call

One is more correct, the other is more accessible.

Misc

Some other miscellaneous stuff related to your question: