caines.ca/blog Shell-Shocked Ramblings from the Trenches of Software Development

25Sep/114

JSON is under-defined for REST

I'm working on a toolkit that can hopefully remove some boilerplate from Rails apps that are trying to implement RESTful APIs (specifically in JSON right now), while simultaneously trying to write a production JSON-REST API.  As I start to dig into the details, it's clear to me that JSON is under-defined for the purposes of RESTful APIs.

Of course everyone wants to use JSON because of its simplicity, but that simplicity seems to be the cause of deficiencies in being truly RESTful.  I have to wonder how many other people are really trying to create RESTful JSON APIS when these deficiencies are largely unsolved, or solved only by ad-hoc means.

Deficiency #1: JSON is not Hypermedia

Nowhere in the JSON spec does it talk about how to represent relationships to other hypermedia documents with links.  Sure, we can add that, but we have to agree on how first, or we can't build generic clients.

Originally, I thought to go with a link format like this:

 { "self" : "/example", "next" : "/example?page2" }

Pros:

  • The names in the name-value pairs define the relationship ("rel" in XML link nodes).
  • It works nicely in a list.
  • It's very json-esque in that it's untyped, like all other values in json.

Cons:

  • It's very json-esque in that it's untyped.  This means that a client can't tell if it's a hyperlink or not without out-of-band knowledge.

That con leads me to believe that this format is unsuitable for hypermedia.

The second idea I happened across was this one :

{"link" : { "href" : "/example", "rel" : "self"}}

PROS:

  • It clearly lets the client know that it's dealing with a link

CONS:

  • You can't have more than one of these at the same level of a hash because names are supposed to be unique.  Soooo... You end up having to wrap these in an array and name that array.  Wow, that's going to be unnecessarily painful to parse.

The third idea I stumbled across and decided was right for me was the one described in the json-schema draft :

   {
     "links": [
       {
         "rel": "self"
         "href": "{id}"
       },
       {
         "rel": "up"
         "href": "{upId}"
       },
       {
         "rel": "children"
         "href": "?upId={id}"
       }
     ]
   }

PROs:

  • Clearly indicates that we're dealing with hyperlinks
  • Allows you to list links with the flattest possible structure
  • Is in a draft for a real standard

CONs:

  • Your links must always be in a array.

I can live with that con.

EDIT (Jan 8th 2012):  I came up with a new way that I think is even better, which better takes clients into consideration.  Here it is:

   {
     "links": {
       "self" : { "href": "{id}" },
       "up" : { "href": "{upId}" },
       "children" : { "href": "?upId={id}" }
     }
   }

This way makes it easy for the client to pull out URLs (eg  doc.links.self.href ) instead of having to search an array, and basically has all the other pros listed in other examples by sacrificing some flatness and using the relationship as the key instead of as part of the link hash.

Deficiency #2:  JSON lacks meta features

JSON hasn't got a standard way of specifying types (like links), or namespaces (for microformats, or embedding other JSON documents), and does anyone really use json schemas?  Those would be useful for specifying subsets of JSON that a client could be programmed to understand in advance... but there goes that simplicity of JSON.

Something makes me think that JSON will need to get vastly more complex if we're really going to use it as part of the semantic web and actually have intelligent automatons understand it.  The people that care about that are in the vast minority at the moment though, and I've actually got real work to do...

Comments (4) Trackbacks (0)
  1. The solution you mention in your *edit* is similar to that of HAL+JSON: http://stateless.co/hal_specification.html

  2. @Trey: Yep. Thanks! The only difference I can see is the underscore on ‘_links’, which I guess is a way of denoting a ‘type’ (or ‘reserved word’ at least), and I think that’s worth following if not for any sake other than standardization.

  3. I’m totally OK with bastardizing technology in any way necessary to solve a problem, whether that problem is ours or our patrons’. It’s just nice to remind ourselves, once in a while, that JSON is just JavaScript that we’ve overloaded with additional responsibilities. If you made JSON perfect for the conveyance of data in a hypermedia system, you’d end up with XML. Oh well. It isn’t necessary to reinvent the wheel, but it’s sure fun.

  4. You might want to take a look at JSON-LD: http://json-ld.org/ (it’s currently undergoing a standardization effort at W3C)


Leave a comment


No trackbacks yet.