I know there has been much discussion of links in this project. This PR attempts to faithfully project RFC8288 style links onto the JSON:API specification. It is very intentionally concise and not feature rich—meaning that it completely avoids topics like hyper-schema, URI templating, inter alia.
If this proposal is not acceptable without those features, I'd ask that this PR be closed. In other words, let's not let those things derail getting a sensible start to better hypermedia support in JSON:API. Nothing here precludes those features. In essence, "a bird in hand is worth two in the bush".
This approach lifts the link-param idea from RFC8288 and serializes them in application/vnd.api+json format under a new params member[1].
The established link-params rel, anchor and rev have special handling, this is my reasoning:
-
rel: inherits from the link object key to maximize backwards compatibility. I used the SHOULD key word for this inheritance to guard against that case that a key may not be a valid link relation type. -
anchor: Because JSON:API has a very well defined structure, I think anchors can be implicitly defined for theapplication/vnd.api+jsonmedia type. In other words, that they don't have to explicitly be added as an object member.I considered adding language to define a new
anchormember that could be placed under anymetaobject so that custom anchors could be used, but I left that out. I think that that choice makes this easier to land and to implement for clients and for servers.The biggest problem I see here is that it makes it difficult for implementors to comply with RFC3986's language about consistency of fragments between different representations. Frankly, I think that's a really pie-in-the-sky requirement to begin with and I wouldn't feel too bad about ignoring it. The
meta.anchoridea could
always be added later if it becomes a real problem.@ethanresnick suggested elsewhere that a fragment should be defined by
typeandid. That would make it easier to meet the consistency requirement, but the problem I faced with that approach is that a fragment also should be able to identify a relationships object within a resource object. A fragment syntax like{type}:{id}(:{relationship field name})?is the naive approach, but falls down because there are no rules for valididformats. I.e., it would break if a resource object'sidcontained a colon (:). Perhaps there are clever ways around that? -
rev: this is deprecated by RFC8288 so I tried to reinforce this with a SHOULD NOT key word.
All other valid link-params are acceptable, like hreflang for example, in addition to any custom ones.
To preclude any misunderstanding with how RFC8288 Link header link parameters are parsed, I added the language stipulating that multi-value parameters must be arrays so that implementors do not try to use space-delimited or comma-delimited parameter values like one would for a Link header.
1: I know I said that this PR should not discuss URI templating, but I just want to step in front of any criticism of the params member name by saying, "adding a vars member would be a perfectly compatible way to support templating later" ;) And that's all I want to say about that :P