Skip to content

Hyper-schema LDO: Replace "method" with behavioral descriptors #94

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
handrews opened this issue Oct 13, 2016 · 6 comments
Closed

Hyper-schema LDO: Replace "method" with behavioral descriptors #94

handrews opened this issue Oct 13, 2016 · 6 comments

Comments

@handrews
Copy link
Contributor

In the current draft, a method of "get" just indicates the existence of a resource (but not necessarily that it can be fetched), while a method of "post" just indicates the existence of some sort of unsafe operation. Using these HTTP terms even though neither of them necessarily maps to those HTTP methods even when using HTTP is very confusing.

Issue #73 proposes an allow hint (see also issue #92 about JSON Home's hints approach). That does not replace the more abstract operation definition. In the abstract, we really just want to indicate behavior, so how about replacing method with one or two keywords that specify behavioral properties directly?

Specifically, "safe" and "idempotent" are the characteristics generally considered to be of interest. This can be done either with a single enumerated behavior keyword that can be set to either of those strings (or left out to indicate no behavioral keys. Or it can be done by using safe and idempotent as two boolean keywords.

I like the boolean option more, except that you have to make idempotent's default dependent on the value of safe. If an operation is safe, then idempotent should default to true. Otherwise it should default to false. Here's what the meta-schemas would look like for each approach.

Single keyword, no default (absent keyword indicates neither safe nor idempotent):

{
    "properties": {
        "behavior": {
            "enum": ["safe", "idempotent"],
        }
    }
}

Here's the two booleans approach, with some fun use of "oneOf" to make default behave ideally (I have no idea how many systems would even handle this properly):

{
    "properties": {
        "safe": {"type": "boolean", "default": false},
        "idempotent": {"type": "boolean"},
    },
    "oneOf": [
        {
            "properties": {
                "safe": {"enum": [true]},
                "idempotent": {"default": true}
            }
        },
        {
            "properties": {
                "safe": {
                    "oneOf": [
                        {"enum": [false]},
                        {"not": {}}
                    ]
                },
                "idempotent": {"default": false}
            }
        }
    ]
}
@handrews
Copy link
Contributor Author

Playing around with this a bit more as I try to write examples for other proposals, I continue to prefer the two boolean properties. While the defaulting meta-schema is a bit convoluted, it is entirely valid, and definitely not more convoluted than what I've seen in both my projects and examples from other systems.

Most importantly, while the default (an annotation keyword) for idempotent depends on the value of safe, validation of each keyword is independent.

@awwright
Copy link
Member

awwright commented Oct 13, 2016

In the current draft, a method of "get" just indicates the existence of a resource

A link describes a relationship between two resources.

Further, adding the "method" property to a link turns it into a form that requires user input. Your typical link will not have a "method" property.

A form is just something that requires user input, and tells a user how they can construct a URI useful to them. For example, how to construct a search query.

Using these HTTP terms even though neither of them necessarily maps to those HTTP methods even when using HTTP is very confusing.

Links exist to relate resources to each other, not to provide a "method list".

Links tell us things like:

  • The author of this document is B
  • The directory above this document is D
  • The previous revision of E is F
  • An HTML form for editing this document is at H
  • A URI for this document is J
  • A document that can visually style this document is at K
  • The next page in this paginated series in L

and so on.

They don't exist to tell us how to manipulate the server state. The protocol, and possibly the media-type semantics, tell us how to do that.

"Safe" and "idempotent" are characteristics of HTTP methods, not resources. So what are you trying to achieve?

@handrews
Copy link
Contributor Author

I apologize for the phrase "indicates the existence of a resource." That should be read as "indicates the existence of a resource related to the current resource in a way described by the rel", but my writing style is too wordy already so I shortened it. I've made a point to repeatedly affirm that I am working from the same definition of links that you are. Nothing you have said here makes me feel otherwise. Everything you have said is stuff I already know and I feel like I just keep agreeing with it over and over in various forms and never getting anywhere.

I am also just extremely unclear on your position. Not an accusation, I am just failing to put all of these things that you've said together the right way with the right context:

But here and in the ODO issue HTML is gold standard and following it is just fine? I probably chopped off some important context from at least one of these quotes, so let me apologize in advance.

I am starting to wonder if my attempts at contributing are more of a distraction than a help. As much as I appreciate everything I have learned in this discussion, I didn't come here to make everyone explain stuff to me or deal with proposals that are so far off that they're time-wasters. I've tried to adjust my communication style and terminology to fit with the project better, but I'm not sure it's working- exhibit A being that I apparently gave the impression that I don't know what a link is.

Any advice appreciated, and if I'm primarily being a distraction I'm happy to step back and see how things go as a lurker. Or just finish copying over old proposals and then step back. I want to see this project succeed, whether that's from helping with proposals or contributing silence :-)

@handrews
Copy link
Contributor Author

I guess the other point worth making in case it has not come across is that this is not an attempt to provide a method list. It was an attempt to figure out what "get" and "post" really mean and convey that in some sort of remotely intuitive way.

I used the "safe" and "idempotent" keywords because if you were considering a "allow" keyword this seemed to be a less protocol-dependent way of conveying important information than actually copying "allow" over from HTTP.

I think controlling whether user input goes into the URI or the request body by setting a property called "method" to either "get" (URI) or "post" (message body) because that's what HTML does using terminology derived from HTTP/1.0 when this is a JSON-based API that is not necessarily using HTTP makes no sense.

If we want to have a keyword that indicates where to put input, it should just say so. However, there is no sense in making another way to put data into URIs when the extended templating proposal is a unified and vastly more flexible approach to work with any aspect of the URI from any combination of instance and user-supplied data.

The only thing that needs a separate mechanism for supplying a schema is the request body, and that, too, should support any combination of instance resolution or user-supplied data to assemble the request.

I have a proposal for all of this data stuff, but at this point it's probably better if I stop proposing things.

@awwright
Copy link
Member

awwright commented Oct 14, 2016

indicates the existence of a resource related to the current resource in a way described by the rel

I don't think even this really best conveys what the purpose of a link is.

Yeah, when you have a link you're implicitly stating that the target exists. But I would say two things instead: It allows resources to be discovered, and it defines a relationship between two pre-existing resources.

And you could even say that the former is implied by the latter, so I just say a link specifies a relationship between two resources.

So, if you have a document like a blog post, there's only so many things you could want to do with it, like look up other posts with the same tag, or see who the author is. These are represented with links.

this seemed to be a less protocol-dependent way of conveying important information than actually copying "allow" over from HTTP.

Yeah, but you can select which HTTP methods to implement at a whim. I can implement PATCH but not POST or PUT for a particular resource, for instance. It's entirely up to the resource. Remember, HTTP is an abstraction by which we manipulate resources. If you try to abstract HTTP (or CoAP, or whatever else there is), all you're going to get is a third or fourth hypermedia control vocabulary functionally identical to HTTP.

@handrews
Copy link
Contributor Author

If you try to abstract HTTP (or CoAP, or whatever else there is), all you're going to get is a third or fourth hypermedia control vocabulary functionally identical to HTTP.

Yeah, that's not what I'm trying to do but I totally see how this proposal ends up there. I agree that this is the wrong approach- I didn't close it due to frustration. I was trying to resolve two things that I saw from you that I thought were in conflict but were not.

My remaining thoughts on hypermedia, if I post them at all, are better handled in a separate issue.

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

2 participants