timshadel
2/16/2013 - 4:14 AM

NOTES.md

{
  "href": "/days/2012-10-24"
  "head": {
    "view": { "src": "/ui/day.ios" }
  },
  "body": {
    "prev": { "href": "/days/2012-10-23" },
    "day": "2012-10-24",
    "goal": {
      "measurement": 76.0,
      "unit": "oz"
    },
    "drinks": {
      "href": "/days/2012-10-24/drinks",
      "data": [
        {
          "href": "/drinks/128472926",
          "timestamp": "2012-10-24T13:04:23Z",
          "loc": {
            "lat": 44.563,
            "lng": -115.864,
            "place": { "href": "https://graph.facebook.com/1735482679", "name": "Riverside, CA" },
          },
          "glass": {
            "href": "/glasses/18362926",
            "pic": { "src": "/images/ac452bfa86c53d8864.png", "type": "image/png" },
            "volume": {
              "measurement": 500.0,
              "unit": "mL"
            }
          },
          "fraction": {
            "number": 0.75,
            "text": "3/4 glass"
          }
        }
      ],
      "data": [
        {
          "href": "/drinks/128472926",
          "timestamp": "2012-10-24T13:04:23Z",
          "loc": {
            "lat": 44.563,
            "lng": -115.864,
            "place": { "href": "https://graph.facebook.com/1735482679", "name": "Riverside, CA" },
          },
          "glass": {
            "href": "/glasses/18362926",
            "pic": { "src": "/images/ac452bfa86c53d8864.png", "type": "image/png" },
            "volume": {
              "measurement": 500.0,
              "unit": "mL",
              "text": "500 mL"
            }
          },
          "fraction": {
            "number": 1.0,
            "text": "Full glass"
          }
        }
      ]
    }
  },
  "footer": {
    "nav": {
    }
  }
}
for user in users
  unless user.isAnonymous
    p
      | We love
      a(href=user.href)= user.name
<orders href="/orders">
  <next href="/orders?page=2" />
  <find href="/orders{?id}" templated="true" />
  <admin href="/admins/2" title="Fred" />
  <admin href="/admins/5" title="Kate" />
  <currentlyProcessing>14</currentlyProcessing>
  <shippedToday>20</shippedToday>
  <order href="/orders/123">
    <customer href="/customers/7809" />
    <basket href="/baskets/98712" />
    <total>30.00</total>
    <currency>USD</currency>
    <status>shipped</status>
  </order>
  <order href="/orders/124">
    <customer href="/customer/12369" />
    <basket href="/baskets/97213" />
    <total>20.00</total>
    <currency>USD</currency>
    <status>processing</status>
  </order>
</orders>
{
  "href": "/orders",
  "next": { "href": "/orders?page=2" },
  "find": { "href": "/orders{?id}", "t": true },
  "admin": [
    { "href": "/admins/2", "title"="Fred" },
    { "href": "/admins/5", "title"="Kate" }
  ],
  "currentlyProcessing": 14,
  "shippedToday": 20,
  "order": [
    {
      "href": "/orders/123",
      "customer": { "href": "/customers/7809" },
      "basket": { "href": "/baskets/98712" },
      "total": 30.00,
      "currency": "USD",
      "status": "shipped"
    },
    {
      "href": "/orders/124",
      "customer": { "href": "/customers/12369" },
      "basket": { "href": "/baskets/97213" },
      "total": 20.00,
      "currency": "USD",
      "status": "processing"
    }
  ]
}
{
  "href": "/orders?summary",
  "head": {
    "find": { "href": "/orders{?id}" },
    "edit": { "href": "/orders/edit" },
    "copyright": { "href": "/copyright", "type": "application/commons-json" },
    "admins": [
      { "href": "/admins/2", "name": "Fred" },
      { "href": "/admins/5", "name": "Kate" }
    ],
  }
  "data": {
    "currentlyProcessing": 14,
    "shippedToday": 20,
    "orders": {
      "href": "/orders?page=1",
      "data": [
        {
          "href": "/orders/123",
          "customer": { "href": "/customers/7809" },
          "basket": { "href": "/baskets/98712" },
          "total": 30.00,
          "currency": "USD",
          "status": "shipped"
        },
        {
          "href": "/orders/124",
          "customer": { "href": "/customers/12369" },
          "basket": { "href": "/baskets/97213" },
          "total": 20.00,
          "currency": "USD",
          "status": "processing"
        }
      ],
      "next": { "href": "/orders?page=2" }
    }
  }
}
{
  "welcome": "Welcome to a haltalk server.",
  "hint_1": "You need an account to post stuff..",
  "hint_2": "Create one by POSTing via the ht:signup link..",
  "hint_3": "Click the orange buttons on the right to make POST requests..",
  "hint_4": "Click the green button to follow a link with a GET request..",
  "hint_5": "Click the book icon to read docs for the link relation."

  "_links": {

    "signup": { "href": "/signup", "title": "Sign up now!" }


    "self": {
      "href": "/"
    },
    "curie": {
      "name": "ht",
      "href": "http://haltalk.herokuapp.com/rels/{rel}",
      "templated": true
    },
    "ht:users": {
      "href": "/users"
    },
    "ht:signup": {
      "href": "/signup"
    },
    "ht:me": {
      "href": "/users/{name}",
      "templated": true
    },
    "ht:latest-posts": {
      "href": "/posts/latest"
    }
  },
}
{
  "href": "/orders?summary",
  "find": { "href": "/orders{?id}" },
  "edit": { "href": "/orders/edit" },
  "copyright": { "href": "/copyright", "type": "application/commons-json" },
  "admins": [
    { "href": "/admins/2", "name": "Fred" },
    { "href": "/admins/5", "name": "Kate" }
  ],
  "data": {
    "currentlyProcessing": 14,
    "shippedToday": 20,
    "orders": {
      "href": "/orders?page=1",
      "data": [
        {
          "href": "/orders/123",
          "customer": { "href": "/customers/7809" },
          "basket": { "href": "/baskets/98712" },
          "total": 30.00,
          "currency": "USD",
          "status": "shipped"
        },
        {
          "href": "/orders/124",
          "customer": { "href": "/customers/12369" },
          "basket": { "href": "/baskets/97213" },
          "total": 20.00,
          "currency": "USD",
          "status": "processing"
        }
      ],
      "next": { "href": "/orders?page=2" }
    }
  }
}
[
  { "_meta:": { "href": "/orders" } },
  {
    "href": "/orders/123",
    "customer": { "href": "/customers/7809" },
    "basket": { "href": "/baskets/98712" },
    "total": 30.00,
    "currency": "USD",
    "status": "shipped"
  },
  {
    "href": "/orders/124",
    "customer": { "href": "/customers/12369" },
    "basket": { "href": "/baskets/97213" },
    "total": 20.00,
    "currency": "USD",
    "status": "processing"
  },
]

I want something like this

<head>
  <script src='' type=''>
  <link rel="contents" href>
<body>
  <a href>data</a>
  <img src="">
  <iframe src="">
  <form href>
    <input>

hrefs are about pointing at other resources

  • sometimes they're related to this thing ()

  • sometimes they're just related to a piece of data ()

  • there's also instructions on where to place the content after navigation (_target)

src is about including other resources in this one

  • sometimes its within this context ()
  • sometimes it makes its own context (

form is about making templates to do stuff, using basic UI controls

  • send data to make a resource (POST/PUT)
  • craft a query to retrieve data (GET)

You don't tend to mix all of these elements together on a single web page, yet many of the hypermedia formats tend to do that, resulting in JSON results that feel a bit awkward.

link's best use, in my opinion, is in Atom Pub

  • navigating a complex hierarchy is really only done using a few standard verbs
  • nearly everything we do on the web can be represented by collections we search and/or browse

XML and JSON already have generic mechanisms to "signal how to interpret the target resource", we don't need to add any more.

represented state may not be exhaustive lists elements may not be the exhaustive set

any object or list which can be retrieved individually may be referenced locally within the hypermedia representation

the natural representation of properties signals the interpretation the natural representation of lists is insufficient to signify

  • it's href
  • how to load more items