views:

66

answers:

1

Hi all

I've been doing a lot of reading lately about how to implement truly RESTful WS's. A lot of people have linked to the article here which details several constraints that implementers should bare in mind if the want to end up with services that conform to the REST concept.

Whilst the post is clearly important, it is unfortunately fairly hard for us mere mortals to understand and various people have tried to decipher it. Perhaps the best explanation I have come across can be found here, where the author gives a concrete example of why many "RESTful" API's out there today really are not RESTful at all and shows how the situation can be rectified.

His proposal leans heavily on the use of embedding links within the representations of the exposed resources and makes a lot of sense: I can clearly follow the logic and would like to employ such techniques myself in a set of services I am designing however I have an issue which I'm not sure how I should resolve: namely how should one provide such links if the data representations used are not XML but something like JSON instead?

Everything the author says makes perfect sense in the XML world but I cannot clearly see how this can be reapplied to other content representations?

Very interested to hear other peoples opinions and see how people may have tackled this problem in their own, non-XML based REST API's.

[edit]: since I wrote this question I've found the following useful links. The go a long way to answering my question but I'm still interested in other people's opinions.

+1  A: 

I struggled with this same question for a long time. I came to two conclusions: a) re-invent XML with a different syntax (basically what those links propose), or b) decide upon some simple fixed conventions.

I went with b. For the api I'm working on now, there are two ways to specify a link as where you can fetch the information.

The first is that the value is always assumed to be a URI in certain cases. The application knows its a URI because thats what our media type says it has to be.

{"form_type": "whatever", "validator": "http://example.com/validatorA"}

The second is that values for a returned structured can either be the typical standard type (int, string, list, object, etc), or an object with the "magic" __ref__ key. This is part of our how we define the media type to look, too ("__" is also illegal in property names by our app's rules, so it should never occur). Its up to the app to dereference the value at its leisure.

{"owner": "john", "attachment": {"__ref__": "http://..."}}

This works for us. Most of the time we care about that the value is the string "john", and less about the abstract concept of "john" is an Owner resource (with more than just the unique identifier "john" as its content).

For our needs, we traded simplicity and performance for expressiveness and REST-correctness. In the real world, its not too big a deal to have out-of-band information that says, "go to /users/$username for more information" when the result provides all the information desired 99% of the time.

Our plan - if necessary in the future - is to attach a link by adding a __ref__ attribute.

{"owner": "john", "owner.__ref__": "http://ex.com/users/83j9io"}

While this isn't as comprehensive as the links you provide, I think its a reasonable balance. While I like the idea that every value can have a link to its unique resource and other meta data (such as described in the json-collections doc you link to), I think that information would be extraneous most of the time. A simple list of values balloons in size, but do you really need to know each value's addressable URI, version, id, etc?

It also introduces annoying complications in the code, having to type ".value" or ".members" (and all the semantics an extra access implies) instead of being able to use language-native constructs. This ".value" model is actually what we do on the server side, and its tolerable only because of all the effort to make them look like standard data types instead of wrappers.

Richard Levasseur
@Richard:Two thoughts / questions:1 - You say "The application knows its a URI because thats what our media type says it has to be.": how have you defined the media-type? Again, for XML this is easy, you use a schema. I don't know of a standard way to do this for JSON, do you? Perhaps this merits a separate question...2: I notice that you are not declaring link type inline. Maybe this is not an issue with only one possible link to follow but if you had multiple choices, surely the media type would be the only way that a consumer would be able to decide which to use?
jkp
The definition is informal and largely self-descriptive (the data is highly dynamic, so "its an object with key:value pairs" about sums it up). btw, I found this through your links: http://json-schema.org/. For media types in links, i personally think that should be left out (and left to the Accept header). The URI is, after all, the _concept_ of that resource, not the specific JSON, XML, HTML, etc representation (at least, thats how i like to think of it).
Richard Levasseur
(forgot to add, by "media type", i'm assuming you mean something like "application/json", not the "self" or "rel" I've seen in atom examples)
Richard Levasseur
Good pointer to json-schema, might come in handy that. Accepting your answer since it was the only one and a pretty good one at that :)
jkp
There is no need to have xml schemas to define a media type (xhtml doesn't have a normative xsd for example), and in my opinion schemas are plain evil. The validity of the structure of your document is largely irrelevant, the only relevant point is this: is there enough infromation in this payload for me to process the request. I find prose to be quite enough to document the expected data strctures any URI may return.
serialseb