Practical Hypermedia APIs

Ditching the Dogma and Getting Stuff Done

Created by Matthew Reinbold / @libel_vox

hypermedia?

(An Extension of Hypertext where Graphics, Audio, Video, Plain Text and Hyperlinks Combine for Non-Linear Navigation)

[TL:DR; It's Linked Content]

Ted Nelson

(1965)

"Let me introduce the word ‘hypertext’ to mean a body of written or pictorial material interconnected in such a complex way that it could not conveniently be presented or represented on paper."

Tim Berners-Lee

(1989)

"I just had to take the hypertext idea and connect it to the TCP and DNS ideas and — ta-da!— the World Wide Web."

Roy Fielding

(2000)

"What needs to be done to make the REST architectural style clear on the notion that hypertext is a constraint? In other words, if the engine of application state … is not being driven by hypertext, then it cannot be RESTful… Period."

RPC vs REST

What's the big deal?

(aka, Who Pooped on Roy's Transactional Parade?)

(Web) Software is Eating the World!

— Marc Andreessen (2011)

APIs are Eating Software

— Steven Willmott (2013)

But …

On the Web, Call


Request Url: http://lh.pigskinspy.com/players/12345
Request Method: GET
Status Code: 200
Params: {}						
						

Response Headers


Status Code: 200
Content-Type: text/html;charset=UTF-8					




						

Call


Request Url: http://lh.pigskinspy.com/API.cfm/players/12345
Request Method: GET
Status Code: 200
Params: {}						
						

Response


Status Code: 200
Content-Type: application/json;charset=UTF-8					

{
    "players": [
        {
            "firstname": "Peyton",
            "lastname": "Manning",
            "team": "DEN",
            "position": "QB",
            "id": "12345",
            "news": [
                {
                    "id": "aaa",
                    "title": "Eli thought Peyton was done"
                },
                {
                    "id": "aab",
                    "title": "Manning proud of his ducks"
                },
                {
                    "id": "aac",
                    "title": "Autographs at all time high"
                },
                {
                    "id": "aad",
                    "title": "Can get happy feet"
                }
            ]
        }
    ],
    "errors": []
}					
						

RTFM

WTF?!

The Tyranny of Fiat Standards

Cambrian Explosion of Media Types

JSON API

HAL

Siren

Atom-pub

Mason

Collection+JSON


Status Code: 200
Content-Type: application/collection+json;charset=UTF-8
{
    "collection": {
        "version": "1.0",
        "href": "http://lh.pigskinspy.com/API.cfm/players/12345/news",
        "items": [
            {
                "href": "http://lh.pigskinspy.com/API.cfm/players/12345/news/aaa",
                "data": [
                    {
                        "name": "title",
                        "value": "Eli thought Peyton was done",
                        "prompt": "Article Title"
                    }
                ]
            },
            {
                "href": "http://lh.pigskinspy.com/API.cfm/players/12345/news/aab",
                "data": [
                    {
                        "name": "title",
                        "value": "Manning proud of his ducks",
                        "prompt": "Article Title"
                    }
                ]
            }
        ],
        "queries": [
            {
                "rel": "search",
                "href": "http://lh.pigskinspy.com/API.cfm/players/search",
                "prompt": "Search",
                "data": [
                    {
                        "name": "playersearch",
                        "value": ""
                    }
                ]
            }
        ]
    }
}							
						

What's your type?

  1. Define use cases. These are "States".
  2. Define affordances (hypermedia controls) the get client to a state.
  3. Identify the parameters with the affordances.
  4. After determining all affordances for all desired states consolodate with a D.R.Y. process.
  5. With full vocabularity for the domain defined, select a media type that best matches.
  6. Let service providers determine which appear, keeping in mind that transitions between states are stateless. Don't create "paths" to a single state.
  7. Build client apps that recognize the stateless nature.

Hypermedia API Process Example

Mr. Football, the dashing, dabber gentleman mascot for PigskinSpy

Defining the Use Cases, Our "States"

  • listAllPlayerNews
  • listPlayerNews
  • listTeamNews
  • searchNews
  • searchPlayers
  • updatePlayer

Affordances: How to Update a Player?


Identify the Parameters

Model the Returns


Status Code: 200
Content-Type: text/html;charset=UTF-8					
						

-or-


Status Code: 404
Content-Type: application/collection+json;charset=UTF-8

{
    "collection": {
        "version": "1.0",
        "href": "http://lh.pigskinspy.com/API.cfm/players/12345a"
    },
    "error": {
        "title": "Player Not Found",
        "code": "404",
        "message": "The player does not exist"
    }
}							
						

Distill!

listPlayerNews listTeamNews

Just a Matter of Filters?

Pick a Media Type



 

 
	News Feed for Peyton Manning
	PigskinSpy All the Breaking NFL News.
	
	
	urn:uuid:60a76c80-d399-11d9-b91C-0003939e0af6
	2014-02-01T18:30:02Z
 
	
		Eli Thought Peyton was Done
		
		urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a
		2014-02-01T18:30:02Z
	
 	
		Peyton Proud of His Ducks
		
		urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa77
		2014-01-31T18:30:02Z
	

						
Build!

Practical Considerations

Batman API smackdown

Seen via Troy Hunt, "Your API Versioning is Wrong"

Bikeshedding

Y No Use?

Dark Matter Development

Wrapping it Up

Questions?

Matthew Reinbold

create@voxpopdesign.com
http://voxpopdesign.com
@libel_vox