Skip to content

Instantly share code, notes, and snippets.

@bradgessler
Last active Dec 29, 2015
Embed
What would you like to do?
JSON is too verbose for hypermedia APIs. HON (Hypermedia Object Notation) preserves the readability and implicit data structure of JSON while with the addition of line attributes for URL and pagination metadata. From http://bradgessler.com/articles/hon/
{
name: "Todo List",
items(href: '/lists/1203/items', next_href: "/lists/1203/items?page=2"): [
item(href: '/items/1'): {
description: "Pick up pizza",
status: "completed"
},
item(href: '/items/12'): {
description: "Eat pizza",
status: "non_started"
}
]
}
@bradgessler
Copy link
Author

bradgessler commented Nov 30, 2013

I would limit the key attributes ({key(attributes): value}) to hrefs that help HON client load and navigate datasets from the service.

{
  list(href: '/lists/1'): {
    name: "Todo List",
    items(href: '/lists/1203/items', next_href: "/lists/1203/items?page=2"): [
      item(href: '/items/1'): {
        blog_href: "http://example.org/xxxxx",
        avatar_href: "http://example.org/yyyyy",
        description: "Pick up pizza",
        status: "completed"
      },
      item(href: '/items/12'): {
        blog_href: "http://example.org/qqqqqq",
        avatar_href: "http://example.org/zzzzzz",
        description: "Eat pizza",
        status: "non_started"
      }
    ]
  }
}

I'm trying to avoid nasty metadata structures that are emerging in JSON hypermedia standards that would make this look like:

{
  href: '/lists/1',
  name: "Todo List",
  items: {
    href: '/lists/1203/items',
    links: {
      next: "/lists/1203/items?page=2"
    },
    collection: [
      {
        href: '/items/1',
        description: "Pick up pizza",
        status: "completed",
        blog_href: "http://example.org/xxxxx",
        avatar_href: "http://example.org/yyyyy"
      },
      {
        href: '/items/12',
        description: "Eat pizza",
        status: "non_started",
        blog_href: "http://example.org/qqqqqq",
        avatar_href: "http://example.org/zzzzzz"
      }
    ]
  }
}

When words like "collection" emerge within a data structure like JSON I feel like we're doing it wrong. I've also seen a number of JSON hypermedia standards preface keys with an _ to denote meta data (e.g. _href) which also feels like an anti-pattern.

Interesting, look what happens when my first example is implemented as Haml XML:

!!! xml
%list{href: '/lists/1'}
  %name Todo List
  %items{href: '/lists/1203/items'}
    %link{rel: "next", href: "/lists/1203/items?page=2"}
    %item{href: '/items/1'}
      %link{rel: "blog", href: "http://example.org/xxxxx"}
      %link{rel: "avatar", href: "http://example.org/yyyyy"}
      %description Pick up pizza
      %status completed
    %item{href: '/items/12'}
      %link{rel: "blog", href: "http://example.org/qqqqqq"}
      %link{rel: "avatar", href: "http://example.org/zzzzzz"}
      %description Eat pizza
      %status non_started

I notice a few problems:

  1. I need to think more about how a hypermedia client would figure out that the <items/> attribute contains a collection of <item/>'s
  2. The %link elements feel too generic and contrived for this example. They would make more sense if the links were attachments like %link{rel="attachment" href="pizza_receipt.pdf"}.

Interesting how the development community at large might be blowing up JSON into the complex monstrosity that XML was in the early 2000's.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment