Search code examples
resthateoashypermedia

How to deal with per verb permission in Rest on a client?


Lets assume we have a resource on an URL like so: foo.com/api/bar And lets say that a user might be allowed to GET that resource, but not allowed to POST to that resource.

I can easily solve that by specifying different permissions per verb. But how should the client know on beforhand if it is allowed to perform the POST?

Lets say we have a "save" button on a page, that should not be enabled if the user lacks the rights to do a POST.

I know about HATEOAS/Hypermedia constraint, and that I can pass a list of links for different actions together with the resource. But AFAIK, that doesn't carry information on what verbs to use, only URL's for different actions. Are there other variations where the verb is included?

Are there other approaches if you don't want to clutter the resource with all sorts of metadata?


Solution

  • This has been asked a lot on the HAL discuss forums https://groups.google.com/forum/#!forum/hal-discuss

    The fact that verbs aren't returned is a decision of the hypermedia format you're using, which i'm guessing is HAL (or maybe collection+json). Some formats DO include verb information.

    HAL actually allows you to include custom fields on your link objects if you wish, but i would discourage this because any standard client won't know how to interpret this.

    But also i've found the verb to be worthless in the end.

    First off in human 2 machine the user is going to read documentation. HAL has all of it's links dereference (via CURIE's as they are currently naemd) to human readable documentation that should describe the effects of requesting that link with different parameters, verbs, headers, etc.

    Next off is that for your Application to be truly RESTful you should respond to all verbs...you might just not respond that the verb was OK. For an HTTP based app returning a 405 is VERY appropriate. Returning a 404 is not! A 500 would be worse!. Your 405 should include what methods are available for the requested resource.

    Next in the case of machine 2 machine (and a bit of h2m) your application when accessed via HTTP (i try to avoid http in my answers as RESTful applications aren't necessarily HTTP..although i'd say 101% of them are) should use the OPTIONS method (http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html) against the resource URL in order to get a description of what's possible.

    Here's where i see a lot of people getting tripped up, what should the response of OPTIONS be? well what people forget is content type negotiation! The requester should say what format for option information they expect. Accept: some-machine-language/xml or application/language+json. Some RFC or standards define these content types and your API can identify what formats it supports. I would suggest you include support for text/html so that you can return human readable documentation as well about what verbs are supported. This covers the h2m scenario nicely.

    The same content type negotiation can be useful when returning info about a method not being supported. The server can send a content-type that the client can understand that describes semantically what methods are allowed.

    The final thing i like to point out is that methods imply client intent. i want to PUT this resource or DELETE that resource. The server should accept requests and return responses indicated what state transitions occurred because of that request. Thus it's a little silly to have the API identify possible intents of the client with every request. The client knows what it wants to do, it should try, and if it can't then it should deal with that.