I've been interested in Hypermedia for quite a while. I bugged Darrel Miller and Glenn Block (Glenn Miller) so much so they created a YouTube show called "In The Mood for HTTP". I bought their book "Designing Evolvable Web APIs with ASP.NET", I am waiting for "RESTful Web Clients Enabling Reuse Through Hypermedia" by Mike Amundsen, I have written about how to return different media types with NancyFX and I am looking at going to restfest.org in Edinburgh this year, a REST conference.
After speaking to Darrel he told me that's the one thing clients do know ie/ what rels an API should return. See here. I was still confused at this, I assumed that the client would have an in memory set of rels that it knew about and therefore understood them but then I was confused what would happen if a new rel was introduced by the API, how would the client know what to do?
I had it in my head and maybe from some of the hypermedia client articles and videos that I'd read/seen that a hypermedia client was some kind of magic client that just knew how to navigate an API. I then came across this article written by someone who also had the notion that a client is some magical thing and he states :
a single client that could make use of *every single (properly built) REST API in existence* without requiring documentation At this point I kind of agreed with him, where are the magical clients and libraries that I can just plug into my API? They must exist as people keep going on about how if you have a client it should know how to work with your API. I then came across this article, it also poo-poos the idea of hypermedia and magic clients but then I started to read the comments and saw comments from Glenn Block, Mike Amundsen and Mike Kelly, the heavy hitters of the API world and it clicked from one of Glenn's replies.
There is no magic client. Its that simple. Yes they could potentially loop over a resource in a response and display data that could in time be added to by the server but the way it navigates the API by pre-defined rels is because the developer who is using the client has documentation about the rels and the payload. Glenn's comment
"Hypermedia api’s don’t prevent documentation, that is a central part. The documentation centers around the link rels and payload, not the uri structure." This also confirms what Darrel said, I just didn't get it at the time.
Clients know about rels, or to be more precise, the developer writing the program that uses a client library to navigate an API has documentation about the rels the API uses and the payloads it returns. So you explicitly put in your code "execute a request to the URL returned in the link that has the rel X", there is no discovery in that sense, it doesn't magically find its way around as such. It doesn't hardcode URLs which is one thing where hypermedia clients aim to succeed ie/no hard coding of URLs to follow and new features and/or rels will need developer interaction to change how their client uses these new features. Glenn sums it up quite well in his quote (I tried to link to the comment but that's not available):
Clients have knowledge of what to expect. In the real world the average hypermedia client knows about certain types of links that may come back. That is all the rel is, and identifier that the client can use to match up against links it cares about. If new links come back that it doesn’t know about, well it will ignore those links. Although the client knows about a set of rels, it does not know if they will or will not be present. The advantage is that logic sits with the server where it can, and often does at some point change. The change might be due to several reasons, including scale as the server can tell the client go get that resource over here rather than where you got it last time. The client also doesn’t know or care about the URL, all it knows is if the rel is this, and that is a resource I want to access, follow that URL.
As to the new links that were returned which that client ignored, newer clients can come along and they are coded to understand those rels. They know what to do with it so they follow it.
In both cases I mentioned there’s no magic and there’s still hard coding of some logic. It’s just the type of logic is different than it is today. Instead of hardcoding uris, and logic of whether or not those resources can be called, the logic is looking for the presence of rels, and decided which one to access. And often the decision of what to do is still decided by a human being, or it maybe be a combination where the machine first looks at the available set and if it’s logic allows it to proceed it does, otherwise it gets interaction from a human.
So there it is, hypermedia clients are not some magic tool/library that can see your API and go "I got this", the developer has to deal with new features however, the key is that if the server modifies existing urls in a rel the client will not have to change because it hasn't hardcoded anything inside it to go to a certain URL. New features in an API should in theory not break existing clients.
Bringing this back to all the different media types that the server can return and all the discussion I see around them. In simple terms the client will always look for a rel, that is common across all media types. The difference comes where the client looks for them in the response payload. Each media type has its own format and therefore where the rels exist. One thing to clarify, the different media types all contain rels for link objects but media types like Siren and Collection+Json have objects in the payload that describe how to add/modify data that may not have a rel but will have a href to show where to send the request to add/modify data.
My next plan is to write a simple API and a simple client using libraries that know how to deal with the media type I use and to navigate it to see how I get on. I've already been told that dynamic languages are more suited to clients than statically typed languages due to static languages requiring a binding of a payload to a resource/model class. With dynamic languages you dont need to map a payload to a class, you can just use a property from the payload directly without the need to bind to a class of 10 properties and then only use 2 (although in theory you wouldn't need to create the 8 properties if you weren't going to use them).
Anyway I hope that has highlighted and answered anyone's question of what a hypermedia client is. If you read this and thought "jeez you're a dumbass, you still don't get it" feel free to let me know in the comments although if I still haven't grasped it by this point, I might cry a little inside. Thanks for reading.