Back to HATEOS and APIs

REST-like discoverability could also be a boon for some services. What if Twitter provided something like this along with a tweet’s JSON?

  "actions": {
    "Retweet" : { "method":"POST", url:"/1/statuses/retweet/12345.json" },
    "Delete" : { "method":"DELETE", url:"/1/statuses/destroy/12345.json" },
    "Report Spam" : { "method":"POST", url:"/1/statuses/retweet/12345.json", params:{"id":12345} }

YES. I had talked about this in the HATEOS post that I wrote a while back. Right now, only html is self-discovering. XML and JSON docs should also have self-documented descriptions of next actions a client can take. That way, you’d cut down on the amount of documentation requires to understand or use an API.

One good point brought up in the comments in that last point was that if I had internal links, a client is likely to know what to do with what it gets back. But if I linked outside of my service, say, how would I understand the schema? There’s no standardized set of tags for geolocation data, like there is hypertext data.

Until we get standard media types for specific kinds of web applications, I’m afraid we’re stuck.


5 thoughts on “Back to HATEOS and APIs

  1. Good to see you thinking about these things :)Honestly (and with no offense intended) I don’t think it’s possible to progress with the example above – if you consider reworking it to an atompub style RESTful application then it all makes a lot more sense, and much of what you need is catered for.Let’s say we have a container which is the /users/timelinea GET on /users/timeline would return a list of say the last 10 items they posted, this could be content negotiated between HTML and an Atom Feed. Each item having it’s own URI of course (say /users/timeline/1234)to POST a new item to the container a client would simply POST to the /users/containerto GET an individual item you would simply GET the /users/timeline/1234 itemto update an item, you would PUT the updated item to the same uri /users/timeline/1234and of course to DELETE we’d DELETE /users/timeline/1234The only two things which aren’t covered by the above, is the case of Retweeting and Spam.First a look at the Retweet – this is actually client side functionality which has been conflated by twitter – technically it should just be a POST of the item to the /retweeters/timeline perhaps with a link rel=”previous” or related link within the item, or a seeAlso or similar.Finally we have the Spam functionality, this could be handled in many ways, but one of the simplest would probably be a link rel=”spam” href=”/spam/?item=/users/timeline/1234″ which when you GET it, asks you to confirm via a form submit (POST).General reply: it may be good to consider RDF as a data format again, as this really makes a lot of things possible, after reading your previous HATEOAS (note the A – …of application state 😉 – two of the primary benefits of adopting RDF are that it allows you to use typed links:/users/timeline/1234 ns0:spam /spam/?item=/users/timeline/1234 .and secondly that when all data is in a common data format like this, then you can pull in data from anywhere in the world (in the same format) and have your application understand it natively, no programming needed, no needing to understand what “retweet” means for this specific service, or what the custom xml vocab used is, it’s all there for you in a way you already understand.Best,Nathan

  2. Thanks for the comment. I think I should take a harder look at RDF like I was meaning to do. It just seems so–verbose.Got recommendations?

  3. I wish I did to be honest, will have a hunt and see what I can find you 🙂 – I can say it’s definitely best to avoid RDF/XML and go for Notation-3 (N3) or Turtle serializations for learning, as they are so much lighter and easier to read.Simply put RDF is just a collection of statements, one after the other, each statement having 3 parts, subject predicate and object – or entity attribute and value if you prefer – called triples. A simple example would be:<http: /> foaf:name “nathan” .<http: /> foaf:homepage <http: /> .where <http: /> is a unique identifier for me (also a uri), the subject or entity we’re talking (making statements) aboutfoaf:name and foaf:homepage are the predicates (or attribute, properties if you prefer), which again are URIs – in this example I’ve used a short namespace prefix’s to keep it compact, but they expand out to full URIs in the normal manner.finally there’s the values, in one case it’s a string, in the other it’s a URI the OO world I guess the above would simply be{ id:, name: nathan homepage:}Whilst there are details and it can seem complex, it’s actually really easy once you grok its simplicity 🙂 and anything in the world, real or not, can be described in this way. it’s very much a universal data model that can be used by all, for anything.The benefits of the RDF model are that no matter how complex or deep your information is, it’s always just a series of triples, one after the other – each predicate/attribute has a globally known identifier so when a machine understands that foaf:name is a name, then it suddenly understands this not for just it’s local data, but for all rdf data in the world – http URIs are also key because they let us give depth, structure, links and unambiguity to our data so I can assert that { #me foaf:interest } and both human and machine can dereference (get) that dbpedia uri to get more information about linked data, and my interests – similarly you can correlate on these uris to say find all people who are interested in the same Linked_Data.There are many, many more benefits but that’s enough for now I think – will see what I can find for you on RDF, linked data and the likes :)Best,Nathan

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s