Subject: [apps-discuss] JSON-Home widget example

From: Jan Algermissen <[email-masked]>
Date: Mon, 8 Apr 2013 13:11:42 +0200

Hi Mark,

curious about your opinion on the following.

The example you provide in the draft[1] troubles me a bit since a real-life, similar case made me look at it from a different angle.

    "http://example.org/rel/widgets": {
         "href": "/widgets/"
       },
       "http://example.org/rel/widget": {
         "href-template": "/widgets/{widget_id}",
         "href-vars": {
           "widget_id": "http://example.org/param/widget"
         },
         ...
       }

What we have here is sort of a standard pattern for making available 'a bag of things' via HTTP.

For example, a bunch of orders can be straight forward exposed as

  /orders

and knowing that

  "http://example.org/rel/orders" : { "href" : "/orders" }

pretty much implies something like /orders/{orderId}, including the idea that adding an order is likely done with a POST to /orders and that editing an order is (maybe) achieved with PUT/PATCH/DELETE.

What troubles me is that JSON Home currently makes it necessary to define two link relations to cover a standard (in a sense) use case that could be covered with just one link relation. Or, in other words, the two link rels somehow semantically overlap, yet demand two 'specifications'. Think in terms of violating DRY.

Can't think of an improvement that does not introduce the 'pattern' into the spec, but I am nevertheless much interested in your view.

Maybe an optional {widget_id} and one rel with appropriate definition does the trick already, but hard to seperate the hints. Dunno...

Jan

[1] http://tools.ietf.org/html/draft-nottingham-json-home-02

---

From: Erik Wilde <[email-masked]>
Date: Mon, 08 Apr 2013 08:55:14 -0700

hello jan.

> What troubles me is that JSON Home currently makes it necessary to define two link relations to cover a standard (in a sense) use case that could be covered with just one link relation. Or, in othe…

Home Documents really don't "make it necessary" to define the link 
relation for the collection. it's simply what the example is using, and 
of course you are free to do it differently. in the end, it is up to the 
service designer to decide which link relations they use/define, and 
which they want to expose in the home document.

our service currently uses "collection" links to link from instances in 
collections to the collection itself, so coming back to your example, 
the only have "widget" links (which are templated), but we don't (yet) 
have a "widgets" link. we're still debating how to best map this to the 
home document we're exposing, and you could make a point that maybe in a 
very rich semantic world, you might be able to say "widget collection", 
indicating that the link points to "a collection of widget things". but 
that, imho, is not really working very well for arbitrary link 
relations, so we are currently leaning towards introducing "widgets" as 
a link relation, because we want to provide such a link to a collection 
in the home document, and we want to be specific about what that 
collection contains.

to repeat myself, i don't think that home documents themselves have a 
lot to say or do here; they simply give you a format for how to expose 
typed links in one place, and what you're exposing there is entirely 
under your control, and your responsibility. hardcoding the "collection 
pattern" into home documents would immediately cause other patterns to 
become candidates as well, and i don't think home documents are the 
right place to start standardizing a couple of ways in which resources 
in HTTP services may be related.

thanks and cheers,

dret.

---

From: Mark Nottingham <[email-masked]>
Date: Tue, 9 Apr 2013 16:51:56 +1000

Hi Jan,

This isn't really specific to home; it's about collections and link relations. It came up some when we were doing 5988, IIRC.

There are a couple of ways of dealing with it. 

One would be to have a "collection" link relation and then put a parameter on it that says what it contains.

E.g., as a HTTP header, it would be:
  Link: </widgets>; rel="collection"; contains="http://example.org/rel/widget"

However, in JSON Home, this becomes:

     "collection": {
        "href": "/widgets/",
        "contains": "http://example.org/rel/widget"
      },
      "http://example.org/rel/widget": {
        "href-template": "/widgets/{widget_id}",
        "href-vars": {
          "widget_id": "http://example.org/param/widget"
        },
        ...
      }

which isn't great, because you can then have only one collection type in your API! It also means that a *lot* of identifying information is lost from the link relation type. If we allowed multiple collection relation types to be defined (for example, by making its value an array of objects), it would introduce an extra layer of dispatch, which isn't great.

If you turn that inside-out, you might end up with something like:

        "container": "/widgets/"
      }

This is succinct, but I'm wary, because the container is "hidden" inside the widget type, and you now need to *very* precisely define the semantics of "container"; if you want to vary from it even a little bit, you're out of luck, because there's no space for adorning it with hints, etc. This approach also precludes mixing different things in the same container (at least obviously).

The way I look at it, what you're asking for here is syntactic sugar. In English, we have separate names for "jar" and "candy" because they're separate things, even though they're often used together.

While it's tempting to define the primitive "jar of candy", I don't want to *start* there, because it'll severely limit the expressiveness of the format, and create awkward special/corner cases.

So, I suspect that we'll always need two relation types to accurately talk about things vs. containers of things. 

That's not to say that we don't need something here, of course; IIRC there is a TODO in the spec for precisely this. I'm just not quite at the point where I know what it looks like. If I had to take a stab now, it'd be something like:

     "http://example.org/rel/widget": {
        "href": "/widgets/",
        "contains": "http://example.org/rel/widget"
      },
      "http://example.org/rel/widget": {
        "href-template": "/widgets/{widget_id}",
        "href-vars": {
          "widget_id": "http://example.org/param/widget"
        },
        ...
      }

Does that make sense? 

Cheers,

--
Mark Nottingham   http://www.mnot.net/