uritemplate icon indicating copy to clipboard operation
uritemplate copied to clipboard

Provide an API for validating URI Templates

Open Julian opened this issue 8 years ago • 9 comments

Hi!

Would you consider an API to validate whether a particular input was valid under RFC 6570 (or does such a thing exist already and I've missed it)?

E.g., http://example.com/dictionary/{term:1}/{term is not a valid URI Template seemingly, but I cannot see an API that complains about that -- uritemplate.URITemplate will happily truncate the end part there and consider that a template with just one field.

(Even having URITemplate do enough validation of its inputs would also work).

Full context: JSON Schema Draft 6 adds a uri-template format. I'd love to use uritemplate to implement it in jsonschema.

Julian avatar Jun 17 '17 18:06 Julian

Hi @Julian! Sorry for the delay. I love jsonschema and would love to be able to provide something useful for it. I don't think there's anything in RFC 6570 for validating a URI Template, but if we can come up with some ideas for a first pass at validation, I'd be happy to keep up with reasonable requests for expansion. That said, I may opt for functionality like what exists in rfc3986 for validation. There, we build a Validator object, tell it what we want it to validate and then pass in a URIReference object. I'm thinking we'd do the same here. Thoughts?

sigmavirus24 avatar Jun 24 '17 13:06 sigmavirus24

Also, could you expand on

E.g., http://example.com/dictionary/{term:1}/{term is not a valid URI Template seemingly, but I cannot see an API that complains about that -- uritemplate.URITemplate will happily truncate the end part there and consider that a template with just one field.

Here's my own experimentation with this:

>>> uritemplate.URITemplate('http://example.com/dictionary/{term:1}/{term')
URITemplate("http://example.com/dictionary/{term:1}/{term")
>>> u = _
>>> u.variables
[URIVariable(term:1)]
>>> u.expand(term=['foo', 'bar', 'bogus'])
'http://example.com/dictionary/foo,bar,bogus/{term'

{term is a valid portion of a URL. I don't know if we'd really want to mark that as an invalid Template. It's entirely possible that {term is an actual part of the URL. =/

sigmavirus24 avatar Jun 24 '17 14:06 sigmavirus24

Hullo! No worries.

Interesting, sorry, not sure how I made that mistake (about truncation). Does look like you're right certainly :).

So I am certainly no expert on RFC 6570 -- I did skim it just now and it does seem like from that 2 minute skim that it seems to be saying things like "when you're trying to expand stuff, if you can't, you return the thing unchanged, and then there's no guarantee that what you get back is a valid URI reference".

So I'm getting a sense that what a "valid" URI template might mean is one that when you expand it ends up expanding into an invalid URI reference according to RFC 3986? In which case maybe I wouldn't actually need any additional APIs, the algorithm would be "find all the terms, expand those with some values, then validate the result as a valid URI reference"?

But yeah I think there's some lack of clarity here (probably on the part of the JSON Schema spec?) on what exactly we mean by "valid URI template" (the example I shared was straight out of our own test suite). @handrews @epoberezkin have I totally missed something here?

That said, I may opt for functionality like what exists in rfc3986 for validation. There, we build a Validator object, tell it what we want it to validate and then pass in a URIReference object. I'm thinking we'd do the same here. Thoughts?

This sounds totally reasonable by the way.

Julian avatar Jun 25 '17 14:06 Julian

So I'm getting a sense that what a "valid" URI template might mean is one that when you expand it ends up expanding into an invalid URI reference according to RFC 3986?

@Julian My reading of the spec was that it is not required at all that URI template expands into a valid URI, there are many places in 6570 that at least imply it. It explicitly says that not all expansions would be valid URIs and also that the character set is wider.

I ended up just constructing a regular expression that [I think] matches ABNF from the spec, feel free to review and use it if you like: https://github.com/epoberezkin/ajv/blob/master/lib/compile/formats.js#L12

epoberezkin avatar Jun 25 '17 14:06 epoberezkin

@sigmavirus24 RFC 6570 prohibits curly braces in literals, they only can surround expressions, so the above is not a valid URI template according to their ABNF (also doesn't match my regular expression). See https://tools.ietf.org/html/rfc6570#section-2.1

epoberezkin avatar Jun 25 '17 14:06 epoberezkin

@epoberezkin you're right. I haven't read the spec in a while and I just noticed

                        ; any Unicode character except: CTL, SP,
                        ;  DQUOTE, "'", "%" (aside from pct-encoded),
                        ;  "<", ">", "\", "^", "`", "{", "|", "}"

I'll have to correct for that.

sigmavirus24 avatar Jun 25 '17 19:06 sigmavirus24

So this is started in #36. I had trouble coming up with validations outside of the unbalanced braces because those "invalid characters" could be converted into their percent-encoded representations per the paragraph above that ABNF.

sigmavirus24 avatar Jul 22 '17 11:07 sigmavirus24

@Julian, this is a friendly ping for your feedback on #36.

sigmavirus24 avatar Jul 31 '17 11:07 sigmavirus24

Hey! Sorry, I was traveling a bit the past few weeks :), will have a look right now, thanks for getting to it!

Julian avatar Jul 31 '17 14:07 Julian