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

Criteria for building hyperlinks #49

Closed
awwright opened this issue Sep 15, 2016 · 10 comments
Closed

Criteria for building hyperlinks #49

awwright opened this issue Sep 15, 2016 · 10 comments

Comments

@awwright
Copy link
Member

awwright commented Sep 15, 2016

Right now, links that use variables that aren't defined are just cast as empty. There should be some way to specify a default value, or to depend on certain variables existing and skip the hyperlink if it doesn't exist.

For example, if there's a schema like

{ links: [
    { href:"/doc/{uuid}", rel:"self"  }
]
}

but multiple posts don't have a "uuid" property, then they all get the same URI of </post/> and all of a sudden we're saying multiple different posts are actually the "same". Oops!

This can sort of be done right now like so:

{ anyOf: [
   {
      required: ['uuid'],
      links: [ {href:'/doc/{uuid}', rel:'self'} ],
    }
]
}

... but this is bulky.

@handrews
Copy link
Contributor

handrews commented Sep 17, 2016

I have thoughts on this but they really need to be part of a much more comprehensive discussion of hyper-schema.

Also, you use doc in URIs in your JSON blobs but post in URIs elsewhere- I assume those are supposed to match.

This gets into how much hyper-schema should enforce about URI usage as opposed to description. It also really needs to get into the extended templating syntax which better allows distinguishing between required URI template elements and optional ones. URI templates do not make this distinction, and we should not impose such a distinction on them.

@awwright awwright added this to the draft-6 milestone Oct 8, 2016
@handrews
Copy link
Contributor

handrews commented Nov 8, 2016

#108 addresses this thoroughly and shows ways to handle both schema-supplied defaults and user-supplied data.

@handrews
Copy link
Contributor

@awwright does using an "hrefSchema" with "default" and/or "required" address this use case?

@handrews
Copy link
Contributor

handrews commented Sep 3, 2017

I'm pretty sure that the following things together solve this problem:

  • The anyOf/required approach for only allowing links under certain conditions. This will become much more intuitive with if/then/else
  • The ability to use required in hrefschema to require input.
  • Both of these techniques can be used together to handle cases where you must have either instance data or client input, but need not have both.

While the required instance field technique is bulky, it is not complex, and I am not convinced the use case is common enough to warrant special syntax. Especially with if/then/else helping things.

Barring a new argument or clarity on how widespread the usage really is, I plan to close this assuming if/then/else is merged.

@handrews
Copy link
Contributor

Note that we found another use case while working out #386, so more work is needed.

@handrews handrews modified the milestones: draft-07 (wright-*-02), draft-future Sep 12, 2017
@handrews
Copy link
Contributor

handrews commented Sep 12, 2017

After thinking this through a good bit, I don't think it's possible to solve this with hrefSchema at all. It is designed to validate input independent of the instance (although the client MAY pre-populate the input with instance data if a variable appears in both the instance and hrefSchema).

Setting a property to required in hrefSchema means that it must be present in the input data set.
But if you want to require something that can't be accepted as input, then what?

The spec says that giving a field a false schema indicates that it MUST NOT come from input data. So I had a momentary thought of setting the field's schema to false but also making it required.

However, that would mean treating hrefSchema a little differently from other schemas. It's not used to validate the data as a whole, it's only for input. So if the schema is false and there's no pre-population, then it cannot accept input, and will fail validation because the field is also listed under required. If there is pre-population, then the input set will fail validation because all values fail validation against false.

What we need is a requirement check that would occur after hrefSchema is used, which is when non-prepopulated instance data is used.

We could change the behavior of hrefSchema to be applied after all resolution of variables to values, but then we would lose the ability to forbid input for a particular variable. If anything, that's a more important use case: most of the time you either want input (such as search params) or instance (such as the identifier of the related thing to search), and not both.

The only thing I can think of is to (sigh) add another keyword, something like hrefRequired which would indicate that a variable must be filled in from somewhere. If its corresponding entry in hrefSchema is false, then that somewhere would have to be the instance.

If no value can be found, then the link is unusable.

I'm not sure I like this, but it's all I have so far.

@dlax
Copy link
Member

dlax commented Sep 12, 2017

@handrews I agree with your analysis.

Looking at values modifiers in RFC 6570 (URI Template) I was thinking it would have been useful to have something like {var!} to indicate that a variable is required and that, if missing, the expansion process would result into an error (which we could then treat as an indication that the link is not usable).

@handrews
Copy link
Contributor

@dlax I agree with you, but I'd prefer to let href be fully RFC 6570 compliant, and put all of the weird adjustments into other keywords that modify the data to which the RFC 6570 resolution process is defined.

hrefPointers and hrefSchema (and possibly hrefRequired) tell us how to construct the source data for the RFC 6570 resolution process, and apply additional validation rules that tell us whether the data set is acceptable or not. Once that JSON Hyper-Schema-specific process completes, RFC 6570 is applied exactly as specified.

Earlier drafts had elaborate preprocessing rules for href, which meant you had to understand those when looking at href values. And they didn't even come close to covering all cases anyway.

@handrews
Copy link
Contributor

I think as part of the general reorganization/clarification proposed in #377, I want to lay out this philosophy and the steps of the resolution algorithm more clearly. There are a lot of keywords involved now (up to five: base, href, hrefSchema, hrefPointers, hrefRequired) and it needs to be presented clearly as a holistic process and not just piecemeal scattered across keywords.

handrews added a commit to handrews/json-schema-spec that referenced this issue Sep 13, 2017
This addresses issue json-schema-org#49.

Add a keyword, "hrefRequired", that prevents a link from being
used if a variable named in that keyword's array cannot be resolved
to a value by any available mechanism.

Remove outdated language about non-object instances causing problems,
as this is addressed by "hrefPointers".
handrews added a commit to handrews/json-schema-spec that referenced this issue Sep 14, 2017
This addresses issue json-schema-org#49.

Add a keyword, "hrefRequired", that prevents a link from being
used if a variable named in that keyword's array cannot be resolved
to a value by any available mechanism.

Remove outdated language about non-object instances causing problems,
as this is addressed by "hrefPointers".
handrews added a commit to handrews/json-schema-spec that referenced this issue Sep 14, 2017
This addresses issue json-schema-org#49.

Add a keyword, "hrefRequired", that prevents a link from being
used if a variable named in that keyword's array cannot be resolved
to a value by any available mechanism.

Remove outdated language about non-object instances causing problems,
as this is addressed by "hrefPointers".
handrews added a commit to handrews/json-schema-spec that referenced this issue Sep 19, 2017
This addresses issue json-schema-org#49.

Add a keyword, "hrefRequired", that prevents a link from being
used if a variable named in that keyword's array cannot be resolved
to a value by any available mechanism.

Remove outdated language about non-object instances causing problems,
as this is addressed by "hrefPointers".
handrews added a commit to handrews/json-schema-spec that referenced this issue Sep 19, 2017
This addresses issue json-schema-org#49.

Add a keyword, "hrefRequired", that prevents a link from being
used if a variable named in that keyword's array cannot be resolved
to a value by any available mechanism.

Remove outdated language about non-object instances causing problems,
as this is addressed by "hrefPointers".
@handrews
Copy link
Contributor

Merged #404

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

No branches or pull requests

3 participants