Skip to content
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

form semantics #294

Closed
handrews opened this issue Mar 31, 2017 · 22 comments
Closed

form semantics #294

handrews opened this issue Mar 31, 2017 · 22 comments
Milestone

Comments

@handrews
Copy link
Contributor

I'm opening this to continue the discussions around the "form" proposal from #280 and #290, which have been closed in order to split everything else from those discussions out into separate PRs (#292 and #293). This issue is for tracking @jdesrosiers concerns that are not addressed by those PRs. Also paging @dlax, @Relequestual, and @awwright.

Everything below the following line is from @jdesrosiers in #290 (comment)
(the quote to which he is respoinding is from @awwright)


Can you elaborate some on how clients, as you would like to see, might act differently for different values of "method" or "form"?

Honestly, I'm a little perplexed by this question. First of all, method doesn't exist in this context. "method": "post" was replaced with "form": true and "method": "get" was removed in favor of hrefSchema. So there are only two possible values. Understanding the difference is no harder than understanding HTML. How does a client act differently when it encounters an <a> opposed to encountering a <form>.

  1. "form": false (default)
    The LDO is analogous to an <a>. Really, it's closer to the Link header, but that's not really the point. A client can do anything with that link that it has enough information to do. A web browser doesn't have enough information to do anything but retrieve it. An LDO with "form": false has more information than an <a> allowing a client to do more things with it based on target hints, but it is basically the same thing.

  2. "form": true
    The LDO is analogous to a <form>. A <form> is a construct for sending data to a resource. A client can proceed taking that assumption into account. For example a client knows it is going to need user input and should prompt the user for that data. This is different from a Link where you would have to first select which method you want to use, then the client determines if it needs to prompt the user for input.

It's pretty obvious how a web browser behaves differently when it encounters an <a> versus when it encounters a <form>. It should be no less obvious for a hyper-schema client encountering "form": false versus "form": true.

@handrews
Copy link
Contributor Author

handrews commented Apr 1, 2017

I've been thinking more about this and how to explain my view that "form" is unnecessary, and that the presence or absence of "submissionSchema" conveys all the necessary information.

HTML is designed to allow browsers to present unambiguous interfaces to users based on hypermedia.

JSON Hyper-Schema (JHS) is designed to inform an automated agent about the possible uses of a hypermedia representation.

The key concept for my philosophical view here are "unambiguous" and "possibilities". These words capture the very different design imperatives behind HTML and JHS.

As a human using an HTML document via a web browser, there are only two things that you can do:

  • Navigate from the current document to another statically identified document
  • Submit data for processing

Behind the scenes, HTML has two ways to handle submitted data (dynamically compute the URI to which to navigate, or submit the data to a statically identified resource for processing, which may involve navigating to a new resulting document or just resetting the current view). The only way that the distinction is visible to the user is that the browser will not allow re-submitting data to a statically identified resource for processing without an explicit confirmation from the user.

Within the scope of HTML, you cannot do anything else: there are exactly two user interface possibilities, where one has two underlying mechanisms which are largely indistinguishable to the end user. While HTML's script and link tags are also hypermedia, they are invisible to the end user and therefore not relevant to the comparisons in @jdesrosiers's comment above.

It doesn't make sense for HTML to have a way to indicate multiple possible uses of a target resource, because there is no universally sensible UI for such a thing, and the entire purpose of HTML is to construct a UI out of hypermedia. So in the relatively rare case where you want the same linked resource to be used in multiple ways, you connect to it multiple times, in each way that will produce the correct UI for that use.

You also do not have generic link relation types for anchors and forms. They mean what they mean, and any additional meaning is provided by natural language text that is significant to the end user but the contents of which are not examined or used by the browser (just displayed).

Web browsers are both generic hypermedia agents and end-user applications, and HTML's design reflects that combined use case.


On the other hand, there are no inherent limits to how an automated agent may interact with a machine-comprehendible resource, such as one represented by a JSON Hyper-Schema + a JSON instance. There is only one link serialization syntax, which is the LDO. The set of possible semantics is infinite, and conveyed by the link relation type. No generic agent can possibly know all relation types in advance.

This makes for a two-layer approach to consuming Hyper-Schema: A generic agent (which is concerned with recognizing what a link could do, but does not have the knowledge of infinitely many relation types to handle each specifically), and an application (which knows the link relation types relevant to its purpose, and can decide based on that what operations are actually available, and knows whether and how to present those available operations to the end user, if any end user even exists).

The JSON Hyper-Schema specification is concerned with the generic agent part. It needs to be clear on everything the generic agent needs to know, including indicating validation rules for various kinds of input data.

However, JSON Hyper-Schema is not concerned with the application part. Designing a set of hypermedia resources in a way that an application can consume them is about designing link relation types, and possibly a further constrained media type (either imposing additional semantics on the instance through a custom application/foo+json media type, or constraining Hyper-Schema to a subset of its full features by declaring a more restrictive meta-schema).


Fundamentally, in my view the form vs anchor distinction is not relevant to the core JSON Hyper-Schema specification. Anyone could easily define a subset of JSON Hyper-Schema that only supports HTML browser presentation behavior. Or they could define link relations equivalent to HTML's anchor and form elements. But this is not a restriction that should be imposed on Hyper-Schema in general.

There are endless possible application use cases that do not map onto the anchor/form paradigm, and JSON Hyper-Schema is responsible for enabling the whole range of possibilities.

@Anthropic
Copy link
Collaborator

@handrews I don't like the name being form, to me that implies ui, post: true/false seems more appropriate to me, ignoring your submissionSchema suggestion if the original suggestion were considered I'd rather see a different name proposed than form.

@dlax
Copy link
Member

dlax commented Apr 1, 2017

@Anthropic I also agree that the name form is not appropriate. Also considering @jdesrosiers's explanation #290 (comment):

Try to view this from a different perspective. You have an LDO with a submissionSchema. The question isn't how do you know you can use it to send data to a resource (POST), the question is how do you know that you can't retrieve it (GET). @awwright wrote up a list of 4 or 5 ways an LDO can be used. That makes it sound versatile, but it is also ambiguous. Say I have an LDO that only supports sending data to an executable resource. I don't want to signal to a user-agent that there are 4 or 5 things you can do with this LDO when there is really only one. Using form allows me to signal that this LDO has one use only: sending data to an executable resource.

In my understanding this kind of restriction would be handled by a Allow: POST header in HTTP. Do we need a similar indication about this in LDO? Can't this be carried by relation name rel semantics?

@handrews
Copy link
Contributor Author

handrews commented Apr 1, 2017

Can't this be carried by relation name rel semantics?

In my opinion, yes, it can and should, but in cases where it's insufficient...

In my understanding this kind of restriction would be handled by a Allow: POST header in HTTP. Do we need a similar indication about this in LDO?

That's issue #73, which is my preferred solution because it's flexible unlike importing some irrelevant convention from HTML.

@handrews
Copy link
Contributor Author

handrews commented Apr 1, 2017

@handrews I don't like the name being form,

@Anthropic: It's not my proposal.

@handrews
Copy link
Contributor Author

handrews commented Apr 1, 2017

@jdesrosiers (from #290):

The web is the reference implementation for REST.

The web as a whole? Yes. HTML? No. HTML is hypermedia format designed for interactive human use, with hypermedia control semantics that are only useful in a human context. HTML is also limited to a smalls subset of HTTP that is completely inadequate for machine-oriented hypermedia, so attempting to apply its semantics in a more fully-functional system doesn't make any sense.

it would be silly to ignore it's lessons or assume they don't apply to our situation.

I'm not assuming anything. The use case of HTML and JSON Hyper-Schema are objectively extremely different.

If you want to draw analogies to the web and call that the basis of how REST should work, fine. But you have to accept the whole web, not just HTML. And that means the JavaScript that you dismiss as "hacks".

@jdesrosiers
Copy link
Member

[We] could define link relations equivalent to HTML's anchor and form elements.

@handrews, I disagree that there is a significant difference between designing for user interaction vs machine interaction. But, I'm going to focus my response on the above statement because I believe this has the potential to move us forward. Defining link relations to give more semantic meaning to links seems like a reasonable way forward. We could define a "rel": "form" instead of "form": true and it would accomplish the same goal. HTML went the route of defining different structures for different things, but technically <script src="foo.js"> could have been defined as <link rel="script" href="foo.js">.

I don't like the name being form

@Anthropic I never thought it was a good name either. It was clear that it was necessary to have something other than method so I proposed the best name I could think of off the top of my head. I disagree that the word form implies UI, but I certainly see how people can see it that way. It's confusing at best. I am certainly open to suggestions for a better name, but you'll have to forgive me for continuing to use it until we have a better alternative.

In my understanding this kind of restriction would be handled by a Allow: POST header in HTTP.

@dlax That is correct, but it's not a good solution for several reasons. First of all an additional uncacheable OPTIONS request is necessary to determine the servers capabilities. This is at best impractical in the real world. We can address that problem by adding to Hyper-Schema an allow keyword that allows us to skip that extra call, but that is less than ideal as well. If we have to fall back on knowing what methods the server supports, it indicates that something is missing in our hypermedia system. That leads us too ...

Can't this be carried by relation name rel semantics?

Yes. But, again, there's a problem. Very few registered relations are actually usable in a generic way, so people end up having to build up their own application specific relations. This means that people have to write their own client that knows how to interpret those application specific relations. Imagine that every time you wanted to use a new web page, your browser would have to be extended to understand that application's custom relations.

That is essentially the bigger picture that I am trying to get to starting with form. One of the reasons the web has been so successful is because it has a simple and generic set of hypermedia constructs (such as <a>, <form>, etc) that any application can use to unambiguously describe itself. That way a generic web browser can run any application. Which bring us to ...

this is not a restriction that should be imposed on Hyper-Schema in general.

If these generic hypermedia constructs can be achieved solely by using a small set of standard relations, then I half agree with you ( @handrews ). That would mean that it is possible to use JSON Hyper-Schema as defined as a building block for a complete HATEOAS system. The part of me that runs around the internet screaming "DECOUPLE ALL THE THINGS!!!" thinks this is a great idea. However, I don't think JSON Hyper-Schema can truly achieve HATEOAS without these standard hypermedia constructs. Those constructs can be in a different document, but it is absolutely essential for it to exist.

@handrews
Copy link
Contributor Author

handrews commented Apr 2, 2017

We could define a "rel": "form" instead of "form": true and it would accomplish the same goal. HTML went the route of defining different structures for different things, but technically <script src="foo.js"> could have been defined as .

Yes, this is the correct approach. And if that is what you need, it should be done as its own RFC because it is orthogonal to JSON Hyper-Schema. As with "collection" and "item", we may want to make a note of how other relation types are to be interpreted in the context of Hyper-Schema, and while I would not use "form" myself I would have no objection to documenting its usage in the context of application/schema+json.

I would be 100% in support of any path forward that involves defining appropriate link relations to convey the semantics you need.

Very few registered relations are actually usable in a generic way

That is not the concern of JSON Hyper-Schema, except to address very generic relations such as "collection" and "item" and define how they can be used within JSON Hyper-Schema. The lack of suitable link relations means that we need to be more focused on either registering more standard link relations to cover the needed use cases, or focusing our API design on defining correct and usable custom link relations. That is by far the most important part of designing a machine-oriented hypermedia system.

That would mean that it is possible to use JSON Hyper-Schema as defined as a building block for a complete HATEOAS system.

Yes, that is the point! JSON Hyper-Schema is a media type. It is one building block in a hypermedia system. It is absolutely not responsible for taking on all roles in such a system.

I don't think JSON Hyper-Schema can truly achieve HATEOAS without these standard hypermedia constructs.

I don't know what "achieve HATEOAS" means here. JSON Hyper-Schema is responsible for providing a functional mechanism for indicating the existence of links with respect to a JSON instance document, and allowing other standard hypermedia constructs such as link relation types to play their designated role in the system. It is not responsible for ensuring that all of the additional hypermedia concepts are implemented.

It is extremely important to keep the purpose of JSON Hyper-Schema, which is a media type, separate from the purposes of other components such as link relation types, URI schemes, and protocols. Picking a favorite set of semantics that would otherwise be indicated by a relation type and hardwiring it into JSON Hyper-Schema through keywords warps the general-purpose nature of the media type and preemptively limits the design choices that should be available by sending people down a specific path instead of encouraging the choice of the correct path for a given situation.

Those constructs can be in a different document, but it is absolutely essential for it to exist.

Certainly, but as their own projects and their own RFCs. As noted, it's fine for JSON Hyper-Schema to refer to other standards (HTTP, collection/item, etc.) that are not media types and provide guidance on their usage in the context of the application/schema+json media type. That can and should bridge the gaps between the often impossibly vague general definitions and actual usage.

But JSON Hyper-Schema does not define the relation types. It simply defines how it uses them.

@jdesrosiers
Copy link
Member

I have always thought of JSON Hyper-Schema as a general purpose hypermedia system because that is the way I have always used it. If we want to reduce that scope to simply a component of such a system, then I'm OK with that as long as we don't stop there. However, I would feel better about the distinction if JSON Hyper-Schema was only LDO.

That is not the concern of JSON Hyper-Schema, except to address very generic relations such as "collection" and "item" and define how they can be used within JSON Hyper-Schema.

I don't see any distinction between using the spec to define new relations and using the spec to add semantics to an existing relation. If defining new relations doesn't belong in the spec, then neither does extending them.

The lack of suitable link relations means that we need to be more focused on either registering more standard link relations to cover the needed use cases, or focusing our API design on defining correct and usable custom link relations.

I think we need to go further. Not only do we need to create a set of generic relations, we also need to identify a set of generic relations that all Hyper-Schema clients should understand. My APIs should be able to use the same client as your APIs and neither of our APIs should rely on custom relations because the generic client only understands the set of relations the spec says it must understand. Defining a custom relation that needs to be anything more than a label would be counter productive because it would mean you couldn't use the generic client. Later on we might be able to extend functionality with some kind of code-on-demand solution, but we should cover the basics first.

@handrews
Copy link
Contributor Author

handrews commented Apr 3, 2017

I don't see any distinction between using the spec to define new relations and using the spec to add semantics to an existing relation. If defining new relations doesn't belong in the spec, then neither does extending them.

So you just think it's irrelevant that RFC 6573 defines "collection" and "item" and gives as reference usages two media types that further define their usage? That is exactly how these things are supposed to work. Declaring that RFC 6573 is completely wrong in its approach is rather presumptuous.

Not only do we need to create a set of generic relations, we also need to identify a set of generic relations that all Hyper-Schema clients should understand.

That is far beyond the scope of JSON Hyper-Schema. There are many possible ways to structure a hypermedia system. If you would like to propose a link relation framework for a comprehensive system, that's fantastic and more power to you. I will cheer you on. But it is almost completely orthogonal to JSON Hyper-Schema, which is a media type. Only media type-specific usage would be part of Hyper-Schema itself (or other media types).

My APIs should be able to use the same client as your APIs

Yes, at the level of understanding generic, standardized media types, link relation types, protocols, URI schemes, etc.

neither of our APIs should rely on custom relations because the generic client only understands the set of relations the spec says it must understand.

No, there is no possible universal set of link relations that covers all scenarios. HATEOAS is not magic, and there are different places where the knowledge of how to use aspects of a hypermedia system should be encoded, and not all of them are generic.

There are link relations, such as "collection" and "item", that represent such generic interaction patterns that they are worth standardizing (in terms of their own semantics and in terms of usage within a media type) and teaching to generic clients.

But for the Cloudflare API, for instance, I will probably want a link relation type something like tag:cloudflare.com,2017:page-rules to indicate the set of page rules that are applicable to the context resource. What are page rules? It doesn't matter. They are a Cloudflare-specific concept, even if someone else has a concept that they call "page rules". To work with them, we define a Cloudflare-specific link relation type. There is nothing useful for a generic client to know about such a concept.

Extended link relations, as discussed in RFC 5988, exist for a reason. Generic clients can't and shouldn't know every possible domain-specific set of link relations. That is the responsibility of domain-specific application code, which uses the generic client, including its understanding of generic link relation types. But the understanding and usage of the domain-specific extension relation types is encoded in the domain-specific application.


Fundamentally, we need to clearly define what JSON Hyper-Schema is and put it in some sort of project charter. JSON Hyper-Schema is not an API description format like OpenAPI or RAML. And it is not a mega-project encompassing everything one could possibly need for the perfect hypermedia API. It is a media type. It does one thing, and it needs to do that one thing well and leave everything else to the separately defined components that provide those things.

@jdesrosiers
Copy link
Member

So you just think it's irrelevant that RFC 6573 defines "collection" and "item" and gives as reference usages two media types that further define their usage?

That's not what I'm saying at all. I don't think it's wrong for a media type to further define a relation. I'm saying that it seems inconsistent for you to say that it isn't OK for a media type to define a relation, but it is OK for it to further define a relation. What's the difference? Why is one "far beyond the scope of JSON Hyper-Schema" while the other is perfectly natural?

There is no possible universal set of link relations that covers all scenarios.

I don't buy that. The web is a very successful counter example. I admit that I don't know yet exactly what it will look like, but the web is proof that a general purpose set of hypermedia controls is possible and can be successful. I'm not suggesting anything that has never been done.

There are link relations, such as "collection" and "item", that represent such generic interaction patterns that they are worth standardizing and teaching to generic clients.

That is exactly what I've been advocating. "collection" and "item" can be the first to be included. I want to identify / create others that define generic interaction patterns and include those as well. I want to have enough of these to be able to express almost anything without ever needing an allow hint. I'm considering execute or executable as a better name than form. It is a common and generic pattern to send data to an executable resource. I don't see any reason why that doesn't belong in the same category as "collection" and "item".

Fundamentally, we need to clearly define what JSON Hyper-Schema is and put it in some sort of project charter.

I totally agree.

@handrews
Copy link
Contributor Author

handrews commented Apr 3, 2017

I don't buy that. The web is a very successful counter example. I admit that I don't know yet exactly what it will look like, but the web is proof that a general purpose set of hypermedia controls is possible and can be successful.

No, you're talking about the human web, and that works because all link semantics are conveyed in natural language and interpreted by human beings (aside from stylesheets and scripts, which are machine-oriented rather than human-oriented).

HTML's anchor and form elements don't convey real semantics, just mechanisms. Which is why I am so opposed to encoding them in Hyper-Schema. Yes, there's some fundamental semantic information in the dichotomy, but the true equivalent of link relation types in HTML is the text between <a> and </a> or on the various form <input /> elements, or even just near the links or forms.

The human web works with a truly infinite number of semantic relation types, many if not most of which are imprecise because natural language. This makes it a perfect example of why you cannot define a set of link relation types that will encompass everything about an API. Using an API is a lot more than just deciding whether to use PUT, PATCH, or POST. Those are mechanics, and largely uninteresting from an API design perspective. The interesting thing is the meaning. The why of using a link, with or without data. Not the how.

I'm saying that it seems inconsistent for you to say that it isn't OK for a media type to define a relation, but it is OK for it to further define a relation. What's the difference? Why is one "far beyond the scope of JSON Hyper-Schema" while the other is perfectly natural?

It's more that a registered link relation should not be media-type specific. Some older ones are, because the whole concept of link relation types developed slowly, and a lot of it came from Atom. But the concept is solid now and has been for some time. So if we want to define a "schema" link relation with its first defined usage to be JSON Schema (not just Hyper-Schema for that example), that would be reasonable.

But most other things should work across media types and are therefore better standardized independent from any one media type. If you have a good relation type, why tie it to a media type? Get it standardized ASAP and then use it anywhere.

I'm considering execute or executable as a better name than form. It is a common and generic pattern to send data to an executable resource. I don't see any reason why that doesn't belong in the same category as "collection" and "item".

Because it's mechanics and not meaning.

@handrews
Copy link
Contributor Author

handrews commented Apr 3, 2017

@jdesrosiers I want to emphasize that I do agree that there are more link relations that can and should be defined to make hypermedia systems more interoperable. I just don't think that either those efforts or Hyper-Schema should be pinned to each other. For one thing, I suspect that you could get some link relation types to RFC and registered with IANA much faster than we'll finish Hyper-Schema.

Even if I disagree with some of your proposed relation types, that's really not important. If you can get other folks on board with an executable relation type as its own RFC, or as part of a package of hypermedia-system-enabling link relation types that make up their own RFC, that's great! I'm not going to get in the way of any effort of that sort.

@dlax
Copy link
Member

dlax commented Apr 3, 2017

@jdesrosiers

In my understanding this kind of restriction would be handled by a Allow: POST header in HTTP.

That is correct, but it's not a good solution for several reasons. First of all an additional uncacheable OPTIONS request is necessary to determine the servers capabilities. This is at best impractical in the real world.

It seems to me, most of the times, a client would already have performed a GET on the target of a relation so the Allow header would be available without any additional cost. In other cases, which I believe would not be the majority, can't we afford a HEAD on the target? Going further and considering non-trivial actions that'd be described by LDO, I even tend to believe the non-cacheable aspect is actually a feature the client should rely on (think of a state system for instance). This is mostly hypothetical thoughts (reflecting my personal experience) because it's not very clear to me what kind of actual actions you'd want to expose with this mechanism. Would you mind providing a concrete example that's not too domain specific?

@jdesrosiers
Copy link
Member

HTML's anchor and form elements don't convey real semantics, just mechanisms.

I agree, but there is precedent for using relations in that way (Atom's edit relation for example). I assume that was why you suggested it in the first place. Or are you are saying it's OK for relations to describe mechanisms, but JSON Hyper-Schema should only describe pure semantic relations? In which case, I don't see the difference between describing a mechanism for adding to a "collection" and a mechanism for executing an "executable" resource. One is just a special case of the other.

No, you're talking about the human web, and that works because all link semantics are conveyed in natural language and interpreted by human beings

I mostly agree. A web application can be looked at as having three parts: server, client, and agent (or user). An agent manipulates the client to affect the server. With the web, the agent is a human, so the client can rely on natural language. When the client is a program, it is far better to have identifiers for semantics so the agent can efficiently and accurately recognize them and behave accordingly.

It's the agent that needs to understand domain specific semantics, not the client. The client needs to understand mechanisms, while the agent needs to understand semantics. The agent makes decisions and the client executes them. The client can and should be generic, but a generic agent (other than a human) is not yet possible (it would take a pretty strong AI). So, really, defining domain specific relations that are purely semantics should be encouraged while domain specific relations that describe mechanisms should be discouraged.

I was thinking about how we can achieve this separation in practice. The Link header allows rel to be a space separated list of values. We could do that too (or an array). For example, assume I have an executable resource that sends an email of the current system stats. I could use "rel": "execute http://example.com/relations/email-stats". I have a unique identifier to program an agent against and my generic client knows what mechanism to use to interact with that resource.

@jdesrosiers
Copy link
Member

@dlax

It seems to me, most of the times, a client would already have performed a GET on the target of a relation so the Allow header would be available without any additional cost.

The way I design APIs, that is generally true. I expect you to GET a resource before you can edit or delete it. But, not everyone designs APIs that way. Not to mention that, not all resources are retrievable. But, even if it is generally true that a GET operation has already occurred, it is unusual for a GET response to return an Allow header. Allow is defined for use with OPTIONS requests and 405 Method Not Allowed responses. I've never heard of it being used as a GET response header, but I guess it's reasonable.

But none of that changes that I don't think the media type should have mechanisms that depend on a particular protocol (HTTP in this case). Those mechanisms should be generic.

I even tend to believe the non-cacheable aspect is actually a feature the client should rely on

I know what you mean. It really depends on the level of chattiness your API can tolerate.

Would you mind providing a concrete example that's not too domain specific?

Does the example at the end of my previous comment help? It's a resource that is not retrievable, so that extra OPTIONS request would be required. You could refactor it so that the resource is retrievable and thus learn that you are supposed to POST. That seems unnecessary.

@handrews
Copy link
Contributor Author

handrews commented Apr 3, 2017

I agree, but there is precedent for using relations in that way (Atom's edit relation for example).

Atom drove a lot of the thought around link relations initially, but like any 1.0 product, it has some quirks. So I consider relations like this to be good first attempts but not necessarily the right models to emulate. Remember also that Atom does a specific thing, so just being an Atom resource conveys some semantics already, reducing the need for the relation type to carry it all.

Even with the Atom edit relation, it's notably that it just indicates that the target is editable; the Atom RFC does not even list exact HTTP methods. It's kind of like the "related" link relation, which exists to allow indicating a related resource with no specific semantics or operational implications. Sometimes you just need a void * :-P

But, even if it is generally true that a GET operation has already occurred, it is unusual for a GET response to return an Allow header. Allow is defined for use with OPTIONS requests and 405 Method Not Allowed responses. I've never heard of it being used as a GET response header, but I guess it's reasonable.

It's completely reasonable, and we shouldn't discount available tools just because they're not broadly used. OPTIONS isn't broadly (much less consistently) implemented either.

Quoting RFC 7231:

An origin server MUST generate an Allow field in a 405 (Method Not Allowed) response and MAY do so in any other response.

So if your API wants to enable caching Allow responses, it should include them in HEAD and GET responses, and document that it does so (in addition to OPTIONS if it supports OPTIONS at all). If your API does not want to enable caching Allow responses, then it should just use it in OPTIONS. But the point here is that HTTP already provides the tools for this, so Hyper-Schema does not need to solve it (beyond the already discussed hinting approach in #73 and/or #296).

The Link header allows rel to be a space separated list of values. We could do that too (or an array). For example, assume I have an executable resource that sends an email of the current system stats. I could use "rel": "execute http://example.com/relations/email-stats". I have a unique identifier to program an agent against and my generic client knows what mechanism to use to interact with that resource.

Per RFC 5988, combinations of relations should not be read to have different meanings from each individually. Neither "execute" nor ".../email-stats" are relation types I would use. I'd have a link relation for a generic email sender, which would document that it sends emails by accepting them for processing (HTTP POST). There is no need to put an "execute" relation on it, because that meaning is carried by the primary relationship. Having a non-executable email sender just doesn't make any sense, so the semantics are clear from just the one relation.

@dlax
Copy link
Member

dlax commented Apr 4, 2017

@jdesrosiers OPTIONS is Not the Method You're Looking For. So yes, as @handrews said, using GET or HEAD is the way to go.

The way I design APIs, that is generally true. I expect you to GET a resource before you can edit or delete it. But, not everyone designs APIs that way.

A prerequisite for building a hypermedia API is using HTTP correctly (and often thoroughly), and relying on headers is essential in this respect. Perhaps it's a matter of "teaching" developers that are ignorant of these aspects, in which case a FAQ would help.

Does the example at the end of my previous comment help? It's a resource that is not retrievable, so that extra OPTIONS request would be required. You could refactor it so that the resource is retrievable and thus learn that you are supposed to POST. That seems unnecessary.

Not sure what you mean by "retrievable" but I'd at least expect one can use HEAD on any resource which is enough to discover supported HTTP verbs (and thus actions). Then using a POST in this very case seems quite natural to me. Also "execute" does not look like an appropriate relation name as it does not describe the relationship between instance and target: it's a verb and should be a noun. Perhaps a custom (domain-specific) relation name is required here.

@handrews handrews added this to the draft-07 (wright-*-02) milestone May 16, 2017
@handrews
Copy link
Contributor Author

handrews commented Aug 20, 2017

@jdesrosiers OK, I just re-read this whole thing :-P

Everything that you want to do is either the province of link relation types or link target attributes.

For link target attributes, we have #296. Any further discussion of target attributes, including caching concerns, should take place there. No matter how you implement it, direct information about what HTTP methods a resource supports is unquestionably a target attribute.

For link relations, nothing you have said convinces me that any of this is in-scope for JSON Hyper-Schema. Here is how I view the scope question:

  • If a link relation is specific to JSON Schema's needs, we may define it here. For instance, we may wish to define a "schema" link relation type (see "profile" media type parameter usage #222 for that).

  • We may, following the example of other media types, clarify the usage of existing link relation types with application/schema+json. For example, "profile", "describedBy", "collection" and "item". If there are other pre-existing link relations that you would like for us to clarify, please file each one (or each set of closely related ones) as separate issues.

  • If a newly proposed link relation type is not driven by JSON Schema's needs, but rather by the general needs of hypermedia systems, it is outside of the scope of JSON Schema. It is true that we could decide to define as many link relations as we want. But that explodes the scope of the project, which is challenging enough as it is. I think it would make a great RFC of its own, but I'm not willing to keep an issue open for it here. Once defined, we may end up revising this specification to clarify more usage.

I don't think there is anything else to do here in this issue. I'll leave it open for a bit in case there is something that I missed that you can summarize, although given the volume of comments already here, I would ask that if you have any new directions of arguments that you file them as a new issue. I think we will get better participation that way.

So to summarize:

  • Discuss any link target attributes in Link usage hints #296
  • File new issues for any new link relations necessary for JSON Schema to function as a media type
  • File new issues for getting clarification of existing link relations into the spec
  • Pursue a complete framework of link relation types outside of the JSON Schema project (if you want to pursue it at all :-)
  • Comment here if I've missed something major that is core to this issue
  • File new issues for new directions more tangentially related to this discussion

@handrews
Copy link
Contributor Author

@jdesrosiers since you've commented on a few other things in the last week, but have not indicated that this should stay open, I'm assuming that you're more or less OK with my suggestions above about which things should get separate issues filed here, and which should be pursued outside of JSON [Hyper-]Schema.

I'm going to close this, because I think it's more likely to confuse new readers than help. It was a fairly confusing read for me last week, and I wrote half the text :-/

There are good ideas in here, but we'll get better feedback on them filed separately as outlined in my previous comment. And of course, do re-open this if my suggested resolutions / re-filings are totally off-base.

@jdesrosiers
Copy link
Member

@handrews There has been an explosion of activity here in the last week and I have very limited time to keep up. I'll get to responding to everything as soon as I can. It's fine to leave this closed because I'm not going to pursue it further, but I'll come back to this issue at some point to give any closing comments once I've had a chance to compose them.

@handrews
Copy link
Contributor Author

@jdesrosiers thanks for being understanding. Closing thoughts whenever you have a chance would be most welcome. I think there is a real path forward for some of the ideas here, I'm just trying to cut down the long confusing issues with no (apparent) actionable focus.

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

4 participants