Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should one provide links in RESTful service using a non-XML data representation?

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.

like image 274
jkp Avatar asked Nov 20 '09 03:11

jkp


1 Answers

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.

like image 100
Richard Levasseur Avatar answered Sep 21 '22 06:09

Richard Levasseur