http://amundsen.com/media-types/collection/examples/
This format takes into consideration collections (much like Siren). It also takes into consideration versioning. However, I'm not certain version matters in the data set if it pertains to an API version. That is best left being in the API URL. It could pertain to collection version, but I'm not sure the point. Documentation says each collection should have a version - but says nothing more about meaning or why.
Items are clearly distinct in this format and are organizationally positioned separate from links.
This is by far the most collision free structure.
However, the data format itself is a bit strange...Every field being an array. Data is always an array of objects. I understand the flexibility this presents and am not 100% against it. I just believe it's perhaps not needed as things could change based on the client application.
The queries section is very nice and something not found in other formats. However, I don't see anything for pagination and I believe it would certainly make sense to include by now.
Collection+JSON puts a lot of emphasis on the display and intended usage of data. Moreso than any other format. This is nice, but unless the client application was attempting to display a layout automatically, I don't see the need. A human engineer can interpret and decide things just fine and perhaps different clients or even access control rules would dictate a different visual representation anyway. Therefore I believe this oversteps the duties a little bit. Still clever and guidance/definition is what we're after of course.
I like how links are even more separate from the data here than any other format. Due to this structure, there is no need to prefix with underscores, etc. Links still carry the same "rel" descriptive values which are important for orientation.
However, I would still use "self" instead of "href" for the current item's link for consistency. Again, Collection+JSON puts some emphasis on how these links should appear. For example, the "render" key. However, many of these properties "render" and "prompt" etc. are optional anyway.
The only downside here is that given how much emphasis and careful consideration is put on how data is rendered, there seems to be a lack of emphasis for "actions" or forms.
The "template" section is actually intended to be used as a guide for which data should be sent to the API in these cases (POST and PUT for update, following convention). However, I don't believe it's particularly descriptive. Also, the format states there should only be one form. This isn't a bad rule of thumb, but I could see where an API response may return multiple forms every now and then (related data, etc.).
http://amundsen.com/media-types/collection/examples/#ex-error
Not shown here is another section called "errors" and I feel this is important and worth mentioning. It's very debatable that errors should be contained within HTTP reponse headers...But I believe that, often, additional detail is required and messages being returned in an API are good because it means those messages can be updated from one central location instead of many client application updates. Superior design for maintenance. Additionally, HTTP headers should be kept small and while a status code is obviously present, an entire message intended for a human is perhaps inappropriate.
{ "collection" :
{
"version" : "1.0",
"href" : "http://example.org/friends/",
"links" : [
{"rel" : "feed", "href" : "http://example.org/friends/rss"}
],
"items" : [
{
"href" : "http://example.org/friends/jdoe",
"data" : [
{"name" : "full-name", "value" : "J. Doe", "prompt" : "Full Name"},
{"name" : "email", "value" : "[email protected]", "prompt" : "Email"}
],
"links" : [
{"rel" : "blog", "href" : "http://examples.org/blogs/jdoe", "prompt" : "Blog"},
{"rel" : "avatar", "href" : "http://examples.org/images/jdoe", "prompt" : "Avatar", "render" : "image"}
]
},
{
"href" : "http://example.org/friends/msmith",
"data" : [
{"name" : "full-name", "value" : "M. Smith", "prompt" : "Full Name"},
{"name" : "email", "value" : "[email protected]", "prompt" : "Email"}
],
"links" : [
{"rel" : "blog", "href" : "http://examples.org/blogs/msmith", "prompt" : "Blog"},
{"rel" : "avatar", "href" : "http://examples.org/images/msmith", "prompt" : "Avatar", "render" : "image"}
]
},
{
"href" : "http://example.org/friends/rwilliams",
"data" : [
{"name" : "full-name", "value" : "R. Williams", "prompt" : "Full Name"},
{"name" : "email", "value" : "[email protected]", "prompt" : "Email"}
],
"links" : [
{"rel" : "blog", "href" : "http://examples.org/blogs/rwilliams", "prompt" : "Blog"},
{"rel" : "avatar", "href" : "http://examples.org/images/rwilliams", "prompt" : "Avatar", "render" : "image"}
]
}
],
"queries" : [
{"rel" : "search", "href" : "http://example.org/friends/search", "prompt" : "Search",
"data" : [
{"name" : "search", "value" : ""}
]
}
],
"template" : {
"data" : [
{"name" : "full-name", "value" : "", "prompt" : "Full Name"},
{"name" : "email", "value" : "", "prompt" : "Email"},
{"name" : "blog", "value" : "", "prompt" : "Blog"},
{"name" : "avatar", "value" : "", "prompt" : "Avatar"}
]
}
}
}
I do like Mason and the use of
@
... I think it's much better than my underscore notation. My only fear is RDF confusion (JSON-LD http://www.w3.org/TR/json-ld)...But I'm trying to think when there might be a potential collision there and I can't, as of right now, find one. The more I go to use RDF perhaps the more I'll be put in that position. Of course@data
at the root of the response would not be interpreted as RDF and anything within it could safely be parsed as RDF or whatever else. So I guess there's no problem...Unless someone blindly parsed the entire response as RDF.Also noteworthy: https://rawgit.com/mamund/media-types/master/uber-hypermedia.html ... One point of "Uber" is to account for there potentially not being any "HTTP" which my above format also handles since
_http
is broken out.Links are within the data (a faux pas in my mind) like many other formats...Contextual links being within the data is fine, but when talking about a class of objects -- it's silly to read the data to pick up a pattern and then wasteful to repeat what otherwise could be a simple regex in someone's code. The only benefit to such repetition is that someone browsing the JSON responses in a web browser could click around the RESTful API.
BUT. IF we are truly saying that the API may not come via HTTP -- then you aren't clicking around anyway. So get rid of self documenting links within the data. There's really no need.
After playing around with my format, I'm also thinking about ditching
_actions
OR keep it (optional) and stick that plus_links
under_http
since they are HTTP related items. Then another protocol can be at the same level as_http
with link children that make sense for the protocol.