The Hypermedia API

Ben Longden / @blongden

Who are you?

Software Engineer & Manager

Inviqa, Session Digital, Sensio Labs UK

Twitter:blongden
GitHub:blongden
Email:[email protected]

Architectural Styles

RPC

http://.../[email protected]& passwd_hash=2ab548fae3162ccfa1a2d41a55557a92& user_name=CrunchAll

Richardson Maturity Level 0

The swamp of POX

Plain old XML

(or JSON)

<user>
    <emailaddr>[email protected]</emailaddr>
    <username>CrunchAll</username>
</user>

WS-*

SOAP

Richardson Maturity Level 1

Identification of Resources

Pretty URLs

No Verbs

Find the nouns

Users can create messages that are visible to other users who follow them.

Craft urls for your resources

http://.../users/{name}
http://.../messages/{id}

Subsets of data

http://.../users/blongden/messages

HTTP as a tunnel

Methods

Metadata

Payload

HTTP is successful

Authentication, Cache, Content Negotiation

Richardson Maturity Level 2

Use the verbs that HTTP provides

GET POST PUT DELETE

OPTIONS TRACE HEAD CONNECT PATCH

Safe actions

HEAD & GET

Idempotent actions

HEAD, GET, PUT, DELETE

OPTIONS, TRACE

Identify States

List users, list a single user

List messages, list a single message

Create/update/delete a user

Follow/unfollow a user

GET /users/blongden/messages HTTP/1.1
Host: example.com
POST /users/blongden/messages HTTP/1.1
Host: example.com
PUT /users/blongden/messages/1 HTTP/1.1
Host: example.com
DELETE /users/blongden/messages/1 HTTP/1.1
Host: example.com

Richardson Maturity Model Level 3

Hypermedia

Hypermedia

Hypermedia is used as a logical extension of the term hypertext in which graphics, audio, video, plain text and hyperlinks intertwine to create a generally non-linear medium of information.

Hypermedia Affordances

[LE] Embedded Links

<img src='http://example.com/logo' />

[LO] Outbound Links

<a href='http://example.com/search' title='view search page'>
    Search
</a>

[LT] Templated Queries

<form method='get'>...</form>

[LN] Non-Idempotent updates

<form method='post'>...</form>

[LI] Idempotent updates

Support for PUT and DELETE

Registered Media Types

HAL

Hypertext Application Language

"_links": {
    "next":   { "href": "/orders?page=2" },
    "self":   { "href": "/orders" }
},
"_embedded": { "order": [
    "_links": {
        "customer": {
            "href": "/customer/bob", 
            "title": "Bob Jones <[email protected]>"
        }, 
        "self": { "href": "/orders/123" }
    },
    "currency": "USD", "total": 30
]}
<?xml version="1.0"?>
<resource href="/orders">
  <link rel="next" href="/orders?page=2"/>
  <link rel="search" href="/orders?id={order_id}"/>
  <resource rel="order" href="/orders/123">
    <link rel="customer" href="/customer/bob" title="Bob Jones <[email protected]>"/>
    <total>30</total>
    <currency>USD</currency>
  </resource>
</resource>
<?php
$hal = new \Nocarrier\Hal('/orders');
$hal->addLink('next', '/orders?page=2');
$hal->addLink('search', '/orders?id={order_id}');

$resource = new \Nocarrier\Hal(
    '/orders/123',
    array(
        'total' => 30.00,
        'currency' => 'GBP',
    )
);

$resource->addLink('customer', '/customer/bob', 'Bob Jones <[email protected]>');
$hal->addResource('order', $resource);
echo $hal->asXml();
echo $hal->asJson();

Link Relations

Short Syntax

"stylesheet", "profile"

Microformats

registered link relations

IANA

registered link relations

Custom Link Relations

http://.../rels/message

Designing a Hypermedia Type

XML or JSON?

HTML? YAML?

JSON

Ubiquitous and easy to parse

Rigid structure

XML

Ubiquitous but harder to parse

Evolvable

{
    "name": "Ben",
    "phone": "07777000000"
}
{
    "name": "Ben",
    "phone": [ "07777000000", "07777000001" ]
}
<?xml version="1.0"?>
<contact>
    <name>Ben</name>
    <phone>07777000000</phone>
</contact>
<?xml version="1.0"?>
<contact>
    <name>Ben</name>
    <phone>07777000000</phone>
    <phone>07777000001</phone>
</contact>

Consider H-Factors

Do you need to extend an existing format?

Why use a registered type?

Existing tools

Interoperability

The 'Chatty API' problem

Zoom

The hypertext cache pattern

http://.../users/blongden?zoom=messages

{
    "_links": { 
      "self": { href: "http://.../users/blongden" },
      "messages": { href: "http://.../users/blongden/messages" }
    }
    "_embedded": {
      "messages": { ... }
    }
}

Common interface

Thank you.

http://joind.in/8048