I'm in the process of designing a REST api and to be as RESTful as it gets i want to incorporate HATEOAS into the json responses.
Adding URLs to related resources is easy enough, but there was some discussion over the structure to use for those links.
A LOT of articles i found use a structure borrowed from ATOM feeds:
"links": [
{"rel": "self", "href":"http://example.org/entity/1"},
{"rel": "friends", "href":"http://example.org/entity/1/friends"}, ...
]
This raised some questions:
"self": "href":"http://example.org/entity/1"
(facebook uses this) or
"friends": { "href":"http://example.org/entity/1/friends", "type": "..."}
The reference should probably be resolved as a url aggain, but would it be bad to include the simple id as well? kind of like:
"sender": {
"id": 12345,
"href": "resource-uri"
}
My way of thought is that while HATEOAS makes it so a client doesn't
need a lot of knowledge to use an api I'm kind of reluctant to remove
the possibility to USE that knowledge (like accessing the profile
picture by building the link client-side without looking up the user
first). Another alternative would probably be to keep the "sender" as an id (or remove it entirely) and just add it as a Link.
Thanks in advance
Steve can you elaborate on what you mean by "multiple relations", i.e. provide an example please?BTW to all, I've been working on two (2) different generic API client projects recently (one for Node.js and one for WordPress/PHP) and they both attempt to treat "REST-like but not RESTful" APIs as if they were hypermedia-aware. IOW, the "hypermedia" links are defined in the client code as opposed to being transferred as part of an HTTP state transfer.While working on these I've struggled with modeling with links only. It seems that links as a building block from which "actions" that use problem-domain-specific verbs to define how to do something useful using a resource (i.e a link) and an HTTP verb. The following is the pattern is what I'm seeing emerge with resources as fundamental and actions that combine a resource and an HTTP verb. The example below illustrates this by extending the conceptual example provided by the OP:
// Also on GIST: https://gist.github.com/3935370{"resources": {"self":{"href":"http://example.org/","methods":"GET"},"friends":{"href":"http://example.org/friends","methods":"GET","vars": {"friend_id": "$.[*].friend_id" // JSON Path}},"friend":{"href":"http://example.org/friends/{friend_id}","methods":"GET,PUT,DELETE"},"new-friend":{"href":"http://example.org/friends/new","methods":"POST"}},"actions": {"add-friend":{"resource":"new-friend","method":"POST"},"update-friend":{"resource":"friend","method":"PUT"},"delete-friend":{"resource":"friend","method":"DELETE"}}}
The example above assumes there is no need to define the "get-self", "get-friends" and "get-friend" action because they are self-evident.Is anyone else seeing this pattern emerge? Have you used it and/or decided to dismiss it? Why or why not?Thanks in advance.
Thanks. I believe Mike Kelly said something like this then:{"first" : "http://example.com/page?page_id=0","prev" : "http://example.com/page?page_id=0",}Why does that not address the issue?
I'm in the process of designing a REST api and to be as RESTful as it gets i want to incorporate HATEOAS into the json responses.
Adding URLs to related resources is easy enough, but there was some discussion over the structure to use for those links.
A LOT of articles i found use a structure borrowed from ATOM feeds:
"links": [
{"rel": "self", "href":"http://example.org/entity/1"},
{"rel": "friends", "href":"http://example.org/entity/1/friends"}, ...
]
This raised some questions:
- Why use an array as a container? According to a java-script dev i know, access to the links would be easier with the links as properties of an object.
(facebook uses this) or
"self": "href":"http://example.org/entity/1"
"friends": { "href":"http://example.org/entity/1/friends", "type": "..."}
- Is there a common json structure (beside adapting atom aggain) to describe references in resource properties? (for example the sender of a message).
"links": [ { "title": "Pride and Prejudice", "method": "OPTIONS", "href": "/books/57", "rel": "item", "description": "Go to Pride and Prejudice by Jane Austen" }, { "title": "The Lord of the Rings", "method": "OPTIONS", "href": "/books/64", "rel": "item", "description": "Go to The Lord of the Rings by JRR Tolkien" }, { "title": "Jane Eyre", "method": "OPTIONS", "href": "/books/71", "rel": "item", "description": "Go to Jane Eyre by Charlotte Bronte" }
]
I wanted to allow multiple links with the same "rel" property which this does not allow. For example, a collection of items could link to each item and provide the same rel property for each:"links": [ { "title": "Pride and Prejudice", "method": "OPTIONS", "href": "/books/57", "rel": "item", "description": "Go to Pride and Prejudice by Jane Austen" }, { "title": "The Lord of the Rings", "method": "OPTIONS", "href": "/books/64", "rel": "item", "description": "Go to The Lord of the Rings by JRR Tolkien" }, { "title": "Jane Eyre", "method": "OPTIONS", "href": "/books/71", "rel": "item", "description": "Go to Jane Eyre by Charlotte Bronte" }
]
Curious why this alternate wouldn't be a better solution?"links": {"items": [
{"title": "Pride and Prejudice","method": "OPTIONS","href": "/books/57",
"description": "Go to Pride and Prejudice by Jane Austen"},{"title": "The Lord of the Rings","method": "OPTIONS","href": "/books/64",
"description": "Go to The Lord of the Rings by JRR Tolkien"},{"title": "Jane Eyre","method": "OPTIONS","href": "/books/71",
"description": "Go to Jane Eyre by Charlotte Bronte"}
],"another": "property"}
In other words, the flat list makes no assumptions about the
importance of any one property of the links. A series of arrays
nested inside an object's named property does.
Good points.
In a specific scenario, I think one could think of *lots* of good
reasons to prefer your option. In a general case, I think I prefer
the flat array.
I guess the ability to reference the rel as a property really resonated with me. I do a lot PHP work and am always frustrated with a get an numerically indexed large array of objects vs. a ID-indexed large array of objects because I have to do the work to find the object rather than just let PHP(/Javascript) do it for me.FWIW.
Yeah, I'm used to being the consumer of APIs too, not the author of them. The server never gives you quite what you want - it's usually close at best.
Yeah. I often feel that API server developers and API client developers don't really want to concern themselves with the issues that the others face. But I digress.
I guess in an ideal world, the client would tell the server exactly how it wanted its data and the server would comply.
I've got an project I'm working on to address that but it's is too early for a public presentation on this list. OTH I'll tell you about it off-list if you are interested.
Hey, maybe I should create a PhD thesis around that concept and then send the development world on a wild-goose chase trying to put it into practice! :-)
-Mikeheh. You better be careful or you might look over your shoulder one day and find a mob of faithful with pitchforks andtorches out for your blood...
M
Cheers,
M
}]
}
Out of interest, did you have any specific use cases that you felt the array approach was better suited for?
On Thu, Oct 25, 2012 at 6:03 AM, Dave Gauer <ratf...@gmail.com> wrote:
>
> Rel being required...what specification requires a rel property? I didn't
> think REST or the concept of HATEOAS got that specific.
>
> But I'm sure you're right that any sort of automated discovery of link
> relations would rely heavily on (or at least benefit greatly from) on a good
> rel naming scheme.
Hey Dave,
The spec I was referring to was the Web Linking RFC:
http://tools.ietf.org/html/rfc5988#section-3
> No, definitely not. Either would work in practice. I'm just trying to
> picture what I might want as a consumer of an API. I think it's very
> difficult to predict how clients will use returned data. An array seems to
> me to assume the least.
Well a link isn't just any old data and the rel isn't any old
property, right? Link relations are a required part of a link because
they are the primary means of identification, so given that I don't
think it's difficult or unreasonable to predict/assume that almost all
client usage of links will revolve around them. JSON gives us a
'native' way to model the relations and their links as key/value via
the JSON Object and makes the links easier to get to, so I think it
makes sense to play to JSON's strengths here.
M