DEV Community

Mike Ralphson
Mike Ralphson

Posted on • Updated on

The Hypermedia Hitchhiker's Guide to Standardised Affordance Metadata

REST is asking Siri "What can you do?" RPC is lookup up a list of commands from osxdaily or trying to guess.

Phil Sturgeon

Babel fish

Let's extrapolate from that a little.

What is Siri's response likely to be, and what would that look like from a REST API?

Siri: What can you do?

Let's bang the root of that hoopy API and see if we get back anything useful.

GET /

Holy swutting Belgium man!

{
    "_links": [
        {
            "rel": "self",
            "href": "/"
        },
        {
            "rel": "siri:whats-playing",
            "href": "/nowplaying"
        },
        {
            "rel": "siri:play-song",
            "href": "/nowplaying/{songName}"
        },
        {
            "rel": "siri:send-message",
            "href": "/messages/{recipient}/{message}"
        },
        {
            "rel": "siri:buy-book-by-title",
            "href": "/purchases/book/{title}"
        },
        {
            "rel": "siri:buy-book-by-title-and-author",
            "href": "/purchases/book/{title}/by/{author}"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

By the way, being a Linux user, I naturally had to get the information for the list above from OSXDaily, which we can think of as a static API description document (a la the OpenAPI Specification), after having to google for it, which we can think of as some kind of API discovery mechanism / registry lookup.

The perennial question now is how do we perform those link relation actions?

“Accessing any hypermedia API in the sophisticated Eastern spiral arm of the galaxy tends to pass through three distinct and recognizable phases, those of Location, Enquiry and Confusion, otherwise known as the Where, What, and How phases. For instance, the first phase is characterized by the question 'Where is this API?' the second by the question 'What can I do with this API?' and the third by the question 'Oh I give up, how am I supposed to know what to do next?”

With apologies to Douglas Adams

It may be obvious that a GET request to /nowplaying will return information on the currently-playing piece of Bach, but to rock out to some Procol Harum, do I POST to /nowplaying/whiter%20%shade%20of%20pale, or possibly PUT or even PATCH the resource representation?

If I want to buy a book by a particular author (I want the original "Last Chance to See" by Douglas Adams and Mark Cawardine, not the sequel by Mark C. and Stephen Fry), can I pass both authors? Do I concatenate them? Do I use an array?

What if I could consult the Hitchhiker's Guide to the API?

Obviously, out-of-band documentation is a REST no-no, but what about in-band documentation?

What if there was a standardised way of retrieving metadata about a resource... such as:

OPTIONS /nowplaying/:songName

Which returned a minimal, dynamically-generated OpenAPI definition for the given endpoint (including any necessary supporting definitions, such as parameters, headers, responses etc).

The OpenAPI format is used to describe the affordances of the endpoint, and the Allow response header gives us the supported HTTP methods for the endpoint to act as indices into the OpenAPI pathItem object.

The affordances metadata can be effectively cached by using the ETag and If-None-Match headers.

If the metadata hasn't changed since the last time the client checked, the API should respond to the OPTIONS request with HTTP 412 - "Precondition Failed" as per RFC7232.

Obviously, other API description formats could be returned based on content-type negotiation.

An alternative to using the OPTIONS method is to include a link with the relation type of service-desc, and link your partial OAS definition that way.

If you want to play with returning partial OpenAPI definitions, I've knocked together a proof-of-concept utility in Node.js - openapi-extract. It works with OpenAPI (fka Swagger) 2.0 and 3.0.x.

References

Aka there's nothing new under the sun

Top comments (0)