Skip to content

Relation Description Object (RDO) #230

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jdesrosiers opened this issue Jan 19, 2017 · 7 comments
Closed

Relation Description Object (RDO) #230

jdesrosiers opened this issue Jan 19, 2017 · 7 comments

Comments

@jdesrosiers
Copy link
Member

I was comparing the HAL hypermedia format with JSON Hyper-Schema and I had an idea.

Background
A link in HAL consists primarily of an href and a rel. The rel is either a IANA registered relation or a URI. The idea is that the URI should link to documentation that describes how the link should be used. This documentation includes the HTTP method you should use with the request as well as what structure the request body should have if applicable. You can see an interactive example of HAL at, http://haltalk.herokuapp.com/explorer/browser.html#/.

JSON Hyper-Schema (draft-04) took a slightly different approach in that instead of having the semantics of the relation in human readable documentation, it allowed you to specify the relation semantics as part of the LDO by using keywords such as method and schema. Being able to describe relation semantics in a machine readable format is what sets JSON Hyper-Schema apart from other hypermedia formats.

Then JSON Hyper-Schema (draft-05) changed the semantics of the method keyword so that it no longer indicated the HTTP method that was to be used. This leaves it up to human readable documentation (much like HAL) to describe the HTTP method to use.

The Idea
So, if we accept that LDO is describing a link AND a relation, what if we split it into two separate definitions: Link Description Object and Relation Description Object. I think this should make everyone happy. The link can be strictly analogous to the Link header (which I think is the direction draft-05 was trying to go). Then the rest can be expressed in the RDO. Those who want link purity get it and those who want machine readable relation semantics including specifying HTTP method can have what they want as well.

Example
Here is one example of how this might be done. I haven't thought out the details too deeply yet. So, this is just a starting off point.

{
  ...
  "links": [
    { "href": "/foo", "rel": "http://example.com/relations/create-foo" }
  ]
}

The rel URI would resolve to an RDO.

{
  "title": "Create a Foo",
  "description": "...",
  "method": "POST",
  "schema": { ... }
}

Pros

  • Separation of concerns
  • Links are directly analogous to HTTP Link header.
  • RDOs could reduce duplication if the same relation semantics appear multiple times in an API.
  • RDOs could be used to augment other hypermedia formats such as HAL

Cons

  • More complicated to learn and use
  • An extra HTTP request is needed to get the RDO (although these should be cacheable forever)
  • More complicated hyper-schema client implementation
@handrews
Copy link
Contributor

@jdesrosiers There are a lot of interesting ideas here, and I'm still trying to wrap my head around the full implications.

My initial reaction is that there's a great proposal here for a media type for describing link relation types and perhaps their usage. I think such a thing would be complementary to JSON Hyper-Schema. A given link relation URI could resolve to such a document, but JSON Hyper-Schema should also function with any link relation type, however specified.

A really key point that has been overlooked is that the way "method" was specified in Draft 04 (to take literal HTTP method names) was an anomaly. I've given an overview of the history, as best I understand it, here: https://github.com/json-schema-org/json-schema-spec/wiki/JSON-Hyper-Schema-and-HTTP-Methods

I'm moving more and more towards the idea that HTTP usage hints are their own thing, and what separates a "service definition" (here is every possible detail laid out and connected) from (hyper-)media types, protocol definitions, general link relation type definitions, and semantic data. The latter four are the building blocks, and a sufficiently intelligent client can work its way through those without explicit connections. Just as a web browser does not need an explicit map of a web site, or how it connects to other sites, in order to move through the site.

But as noted, I still nee to think this through some more. TL;DR, there's some great thought here, I think it might be a separate piece. But I'm open to persuasion.

@jdesrosiers
Copy link
Member Author

@handrews thanks for your comments.

there's a great proposal here for a media type ... I think such a thing would be complementary to JSON Hyper-Schema.

Absolutely. Defining RDO as a media type is primarily what I had in mind. That is what would make this usable across any hypermedia format that uses rel. I agree that this doesn't have to be part of the JSON Hyper-Schema specification. It could stand alone. However, I do think it should at least be part of the JSON Schema family because it relies on JSON Schema. It also constitutes something of a split of the JSON Hyper-Schema specification. Most of the LDO keywords would move to RDO and not a lot else would have to change.

JSON Hyper-Schema should also function with any link relation type, however specified

Yes! That is my favorite part of this idea. It doesn't impose anything on JSON Hyper-Schema. It's just another tool in the tool belt.

A really key point that has been overlooked is that the way "method" was specified in Draft 04 ... was an anomaly. I've given an overview of the history

I've read it. Thanks for doing that! Draft 04 is hardly an anomaly. It is the longest living and most used by far. I don't think it is fair to trivialize its relevance.

Just as a web browser does not need an explicit map of a web site, or how it connects to other sites, in order to move through the site.

I'm not sure, but it sounds like you are implying that RDOs feel like service definition to you. Nothing could be further from the truth. It just gives you a language for creating relation type definitions that a generic client can use without a human having to get in the middle to code the semantics. No explicit map is being introduced. It just automates a piece of the process that currently requires a human coder.

@handrews
Copy link
Contributor

@jdesrosiers my concern here is that you're just moving the explicit naming of HTTP methods out to the RDOs. But a link relation should not be tied to a specific protocol.

When I say something feels like a service definition to me, I mean that it is taking a flexible generic concept and picking a specific concrete implementation of those concepts.

So while a certain amount of concreteness is often introduced by choosing a protocol via the scheme in the URI, there is still quite a bit of flexibility remaining in terms of how that protocol is used with that resource. HTTP provides run-time mechanisms for determining what is available at that moment, either by doing a HEAD or OPTIONS and checking headers, or by trying an operation and getting an error that explains why it is not allowed (and potentially has headers advising what is allowed).

The only part of HTTP that absolutely cannot be determined ahead of time is the request format for POST. While the idea of an Accept-Post header analogous to Accept-Patch has been proposed I do not think it's really gotten any traction. This is why JSON Hyper-Schema LDOs have the "schema" field (the use of "schema" with "get" is an, IMHO, unfortunate legacy of HTML).

So I guess I am wondering what it is about an RDO that is not already handled by the LDO or (in this case) HTTP itself? Why fetch a document describing the relation when we can already get it with a HEAD request?

(also, I didn't mean "anomaly" as in "unimportant", I meant that it was the first attempt at using it that way and at least some of us feel that it introduced at least as many problems as it solved, which is presumably why it was reverted for Draft 05, although that was not my decision so I can't say for certain).

@jdesrosiers
Copy link
Member Author

a link relation should not be tied to a specific protocol

Many of them do. My understanding is that you can define a relation however you want and that can include (without being limited to) how to use the relation with HTTP.

it is taking a flexible generic concept and picking a specific concrete implementation of those concepts.

I don't think it is. It does add specific details for a concrete implementation (HTTP), but it in no way inhibits the flexibility of the generic concept. That's why I see RDO as a good compromise. People who want to use it can use it without imposing anything on those don't.

HTTP provides run-time mechanisms for determining what is available at that moment, either by doing a HEAD or OPTIONS and checking headers, or by trying an operation and getting an error that explains why it is not allowed (and potentially has headers advising what is allowed).

Yes, I know, but I find it unacceptable to have to make an extra uncacheable request or to make requests blindly and hope it's supported. That is the void I am trying to fill. I don't think it is unreasonable to have some hint at what methods are supported. I agree that draft-04 is too flexible in how it supported PUT and DELETE, but at least it supported them.

Thanks for discussing this with me. Clearly there is no interest here for something like this, so I'm going to close this issue. However, I might pursue this or something like it independent of JSON Schema.

@awwright
Copy link
Member

awwright commented Feb 5, 2017

Just to post (or reiterate) my 2¢:

Links describe relations between resources. They make statements like:

<Paper> author <Alice> .
<Alice> type <Person> .
<Paper> tag <math> .

and so on.

It's pretty much out of the scope of JSON Schema to describe how to interact with these resources, only that they exist and their relationship to the current document. Other technologies take up the task of interacting with resources.

However there is one way to declare how to use a resource, using forms. Or more specifically, forms define how to construct a document, which can then be submitted to a resource (in a protocol-defined manner, i.e. HTML's method=post). Forms can also be used to let you construct a link relationship (i.e. HTML's method=get).

@jdesrosiers
Copy link
Member Author

Thanks, @awwright, for your comments. I don't think this RDO concept contradicts any of that great description of how links work. It fits the role of an "other technology" for "interacting with resources". The only disagreement I see here is whether or not it should be in scope for JSON Hyper-Schema. I understand why you draw the line where you do, but I think JSON Hyper-Schema loses some of it's usefulness without the ability to somehow hint that a resource supports PUT and DELETE requests. RDO can provide that without polluting LDO with HTTP protocol details.

But, it doesn't have to be defined here. Defining it as it as it's own entity has it's advantages as well. I like the idea that it could work for HAL as well as JSON Hyper-Schema.

@awwright
Copy link
Member

awwright commented Feb 7, 2017

@jdesrosiers Understandable.

It might be worth noting too that this is a problem that other hypermedia types have, there's not much in the way of hinting at an HTTP resource's capabilities. A good solution would be able to cover many media types, not just JSON Schema.

I fully expect to revisit this as we learn more about hypermedia APIs (and I really hope JSON Schema can be a pioneer in this).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants