23

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

  • 4
    now i want to see pictures of cute cats – Carrie Kendall Jul 8 '13 at 13:49
  • I don't get it. If you don't store 'user level' anywhere, then you can't distinguish. It sounds like you don't have any user info stored on the server either, so you can't store their user level with it. – Jan Doggen Jul 8 '13 at 13:52
  • @JanDoggen I do have the user level on the server (the client conveys the identifier to the server). – Benjamin Gruenbaum Jul 8 '13 at 13:54
  • Help? I don't get the 1337 reference? – Marjan Venema Jul 8 '13 at 20:15
  • Leet – JustinC Jul 8 '13 at 21:00
18

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:

  • 1
    Yeah, this makes absolute sense, though as a side note I find some of the auth(ent/orize) information going in the HTTP headers is an appropriate approach as it is effectively metadata. – Jimmy Hoffa Jul 8 '13 at 15:31
  • @JimmyHoffa It is indeed metadata, and my first thought was to use the HTTP headers. However, in this case, HTTP headers don't offer enough visibility for the customer, and granularity needed for marketing messages. (Edited the answer to add this detail.) – Florian Margaine Jul 8 '13 at 15:32
  • @JimmyHoffa how? An 402 won't do in this case. What do you suggest? – Benjamin Gruenbaum Jul 8 '13 at 15:47
  • @BenjaminGruenbaum I didn't say response codes, I said headers; you can add all the custom headers you want for metadata, it would be wise to have all responses from a restful api just have the users role in the header as a UserRole = level1 or whatever you wish to call it just to ensure consumers are always aware how to present any data they receive, and it's consistent across all responses where the data models coming back will be different from one request to another, consumers can always check their role the same way. – Jimmy Hoffa Jul 8 '13 at 15:54
  • 1
    @BenjaminGruenbaum I've completely rewritten the answer. – Florian Margaine Jul 8 '13 at 17:57
4

How does the client know if they can upgrade their ranking?

That depends on the client. Normally you can put such information in form of a hyptertext message (aka HTML) into the response body of the REST method. However that only makes sense if the REST API is used with a HTML client.

Similar for XML and JSON.


Edit: You might confuse using an API (expand this acronym) with the marketing of your account-types / user-plans. I would not mix this, as it always gets fishy (business decisions might requires faster changes than the changes in the software to communicate different responses due to these changes are able to get on the platter in time).

Instead tell your users through a different channel, e.g. with the newsletter what their benefits are.

This works particularly well when the person signing up to the service isn't the one who is programming against the API. For example:

George (who is a proudly gay guy at the age of 36 loving kittens) buys access to cute-cats-4-me.com and tells his 16 year old spouse (who is well with scripting computer systems incl. linux) to create a digital signage application displaying nice little cutie kitties on the wall in the apartment.

So the guy who is having fun programming this actually is not that much the most straight-forward addressee of the information.

Alternatively in response to login and a user-info method, provide all the gory details.

But when a user requests cats programmatically, she should be already aware why she only gets three cats back or more. But you don't solve this communication problem with code.

Otherwise, allow them to query more and then give back a failure notice if their rights are not sufficient. But again, that's not a user-friendly software.

  • 1
    @Racheet: Do you have a problem when the girls have the money in the house and tell the boys what to do? – hakre Jul 8 '13 at 18:08
  • 1
    I have a problem with an example which asserts that girls need boyfriends to do their programming for them. – Racheet Jul 9 '13 at 9:02

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.