4 ms·
I wrote the spec for application/hal+json that got compared to WS-star , here's where I'm coming from: JSON doesn’t have links. Establishing some basic convent
by AffableSpatula 14y ago
I wrote the spec for application/hal+json that got compared to WS-star , here's where I'm coming from:
JSON doesn’t have links. Establishing some basic conventions for that makes complete sense. Defining those conventions is called a spec. Giving a payload that follows conventions a name also makes sense. Establishing that is called registering a media type identifier.
It makes no sense to keep reinventing the linking wheel in every API . Pretending like a very minimal media type like hal+json is akin to WS-* is incredibly disingenuous and/or stupid.
Establishing a standard media type like hal+json with a bunch of conventions allows us to build generic tooling that can help with both serving and consuming payloads that contain links.
Being pragmatic is great, but misrepresenting a genuine effort to improve the status quo and improve the API ecosystem in a reasonable, non-complicated fashion as ‘hand-waving’ or 'unnecessary' is not very constructive.
- mjs 14y agoAre there any examples of what, for example, the Flickr or Twitter API would look like under hal+json? I'm struggling to see how application/hal+json would help me write a client to upload a photo. I imagine that with or without hal I'm ultimately going to POST the data to some endpoint. The question is, how do I figure out what endpoint to use? Without hal+json I need to read the API docs to discover that "/photos/" is the correct endpoint to post to. But with hal, it seems I still need to read the docs to discover that within the hypermedia file, the key "photos" holds the value for the URI template. So either way, I need to read the docs, and either way, my client breaks if the meaning of the string "photos" changes.
- gamache 14y agoYou still need to know the meaning of each link relation, that is true. When hypermedia advocates gloss over this, or imply that clients will just magically know what to do with all the data and links coming from the API entry point, it annoys me. It's dishonest. But what you gain from link relations is worth advocating for: * Link relations can be standardized across APIs. This opens the door for clients to infer functionality when presented with links it recognizes. There is a list of currently standardized link rels here: http://www.iana.org/assignments/link-relations/link-relations.xml http://www.iana.org/assignments/link-relations/link-relation... * Link relations provide an abstraction layer over the implementation, which may change. They're not unlike an API in and of themselves. As long as the 'photos' link relation does not change, it can point to whatever URL it wants, and that URL or URL structure can change over time without damage to the client. * Using exclusively URLs to identify resources, as opposed to making the client memorize how to take any ID and map it into a URL, frees up an API to refer to resources outside its scope. That is big, enabling multiple APIs to connect as a proper ecosystem, with outgoing and incoming links. We can't do that today.
- msbarnett 14y ago> As long as the 'photos' link relation does not change, it can point to whatever URL it wants, and that URL or URL structure can change over time without damage to the client. So here's where my skepticism kicks in: How often are you really expecting your URL structure to change, in practice? And when the URL structure does change, what percentage of the time does the change in URL structure also coincide with a change in semantics that clients logic will need to be changed to take into account? In my experience the answer to those questions is 1) Very rarely. 2) Nearly always.
- gamache 14y agoYou're preaching for YAGNI, which is a philosophy that's more good than bad, for sure. I am lamenting that doing hypermedia APIs properly isn't the default in Rails. I call out Rails because its massive appeal (to which I am no stranger) is doing It right by default, all over the place for the common case. That obviates YAGNI, because it implies no extra cost incurred for doing it right. I'd rather enable It rather than assume I ain't gonna need It, all things being equal. That said, I have worked in companies large enough that the interlocking pieces are pretty far removed, yet expected to interoperate fully. Having and using link relations could have saved us a couple of headaches. I am hopeful the Rails-api project might approach this with more.... maturity?
- msbarnett 14y ago> That obviates YAGNI, because it implies no extra cost incurred for doing it right. I'd rather enable It rather than assume I ain't gonna need It, all things being equal. All I can say to this is that we have vastly different approaches to engineering. Features are debt. Adding features you don't need now and will probably never need in service of some kind of ideological purity ("doing it right") is the worst kind of deficit spending. I've done my time in big enterprise vast complex interlocking highly abstracted development. For every 1 time prematurely optimizing for flexibility happened to pay off, it resulted in onerous development and maintenance overhead for no benefit 9 other times. Do the simplest thing that works. If you don't need it now, assume you ain't gonna need it and only build it if and when you have a pressing need for it. To me, these are the very core of sound, reliable engineering.
- AffableSpatula 14y agoYour applicaiton's link relations should be URLs. This means that you can expose each bit of documentation for each rel at their URL. So every time you see a link in a hal+json document, you can follow the _rel's_ URL, and fetch the documentation for it.. that turns out to make the API very easily discoverable, and gives you a way to model/manage your API's documentation in a consistent way. You can actually see what that looks like in practice here (click one of the book icons on one of the links on the left): http://haltalk.herokuapp.com http://haltalk.herokuapp.com
- mjs 14y agoDo you mean like http://haltalk.herokuapp.com/rels/signup http://haltalk.herokuapp.com/rels/signup? But every site will have different requirements or mandatory fields on signup, so there's still no "discoverable" way to sign up to Amazon and eBay and Google without a human looking at http://amazon.com/rels/signup http://amazon.com/rels/signup and http://ebay.com/rels/signup http://ebay.com/rels/signup, etc., in which case you're back to still needing to read the documentation. I guess it's a slight improvement to know exactly where the documentation for a particular link relation will live instead of having to search for it, but it doesn't seem to solve an especially difficult problem.
- AffableSpatula 14y agoit is an example of a discoverable API with discoverable documentation though, which is what you were asking for I think.. maybe not?
- mjs 14y agoAh, maybe I misunderstand what you're trying to do. I thought Hal was trying to make it possible to write clients that can buy from Amazon or eBay without knowing anything about the specifics of either. But actually what it's attempting is a sort of machine-assisted documentation system? (Since you still need a human to read the docs to find out how to signup, place orders, and so on.) I can see how that might work, but it doesn't seem like an important problem to solve.
- icebraining 14y agoHypermedia doesn't claim that you don't have to read the docs, that's a misconception. You do have to read and know how to parse the file formats. The main advantage is that know that your application supports Twitter, it also supports every other service that uses the same file formats, since they can be shared, re-used and standardized. Obviously, two services can't use the same URLs, so if you hardcode them, you're locked in.
- mjs 14y agoI can imagine Twitter publishing a application/tweet+json media type or similar, and clients and servers either supporting this or not (and exchanging Accept headers and 415 Unsupported Media Types as they go), but I don't get what that has to do with HAL. For example, the "comments" link relation in http://developer.github.com/v3/pulls/ http://developer.github.com/v3/pulls/ points to https://api.github.com/octocat/Hello-World/issues/1/comments https://api.github.com/octocat/Hello-World/issues/1/comments but no-where in the document does it say what media types that endpoint will accept.
- tlrobinson 14y ago"JSON doesn’t have links." JSON doesn't, but HTTP does. Why not use Link headers?
- AffableSpatula 14y agoLink header parsers are far less ubiquitous than json, and Link headers aren't very good for use cases like representing links that come from items in a collection, there are also issues relating to the maximum feasible size for HTTP headers and/or the header block as a whole. Link relations are useful for adding links to media types that can't support links (e.g. images, etc), and for layering protocols (e.g. Linked Cache Invalidation), but for normal APIs it makes your clients life much easier if you just put them in the body.
- MatthewPhillips 14y agoWould this be a better fit as part of an OPTIONS request? OPTIONS /orders { "GET": { "description": "All the orders." "links": { "self": { "href": "/orders" }, "next": { "href": "/orders?page=2" }, "find": { "href": "/orders{?id}", "templated": true }, "admin": [ { "href": "/admins/2", "title": "Fred" }, { "href": "/admins/5", "title": "Kate" } ] } } }
- bct 14y agoHere's one opinion on that: http://www.mnot.net/blog/2012/10/29/NO_OPTIONS http://www.mnot.net/blog/2012/10/29/NO_OPTIONS
- steveklabnik 14y agoThat's another option, yes.
- deleted 14y ago[deleted]
- jalfresi 14y agoJSON and other non-natively-hyperlinked-media (e.g PNG, MP3, etc) can use the Link header to add hyperlinks. It's HTTP that is hypermedia aware, not the content-type, so you dont have to go out and invent image/png+hal. TL;DR You dont need to create a new media-type to make JSON hypermedia. All requests are hypermedia by virtue of the fact that it uses HTTP as the transport protocol.
- masklinn 14y ago> It's HTTP that is hypermedia aware, not the content-type 1. That's highly debatable, the very content type from which REST was extracted is hypermedia-aware 2. The LINK header only works for very shallow and broad linking, making it contextual to the content type will have as high a complexity (if not higher) as codifying hypermedia in the content type (consider a resource listing other resources, the equivalent to the HN frontpage, how are you going to match a given entry in the media — which may have a number of inline metadata — to its LINK? anchor? now you need to define an anchoring scheme in your content type. A link-extension? Now you need to define that, and you need to define the relation between the link extension and the content type. And of course you also need a custom relationship, which you'll also have to define, and you need your clients to correctly handle upwards to hundreds of LINK in a single resource) (and even with that, you're also making the client more complex because he'll need an explicit link-resolution step... and then, are URI templates allowed at all in a LINK?)