apiaryio / api-blueprint

API Blueprint
https://apiblueprint.org
MIT License
8.63k stars 2.14k forks source link

Tilda (~) as in GET parameter name #387

Closed mieszko4 closed 7 years ago

mieszko4 commented 7 years ago

In my API I have a GET parameter {?~ids} which means "ids that will not be included in response".

However when I try to do this I get a warning:

URI template expression "?~ids" contains invalid characters. Allowed characters for expressions are A-Z a-z 0-9 _ and percent encoded characters

Why do you restrict ~ from GET parameters? See: http://stackoverflow.com/questions/1455578/characters-allowed-in-get-parameter for a reference of allowed characters.

w-vi commented 7 years ago

Good question, it looks like the RFC 6570 allows ~ so should API Blueprint. Seems like a bug rather then feature.

w-vi commented 7 years ago

After reading the RFC 6570 more carefully ~ tilda is not allowed as a variable name. ~ids is not a valid URI Template variable name. See https://tools.ietf.org/html/rfc6570#section-2.3

Basically you can have ~{ids} but not {~ids}

erunion commented 7 years ago

Fascinating.

mieszko4 commented 7 years ago

For me this specification is fascinating, very hard to follow just from the context :) So for now I only believe it is right that ~ cannot be part of variable name - I do not see it yet..

śr., 15 mar 2017 o 01:26 użytkownik Jon Ursenbach notifications@github.com napisał:

Fascinating.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/apiaryio/api-blueprint/issues/387#issuecomment-286604176, or mute the thread https://github.com/notifications/unsubscribe-auth/ADFp4keQ_KXrgQY-qJZ7-LCm-flNA1Z3ks5rlzBPgaJpZM4MbPW0 .

w-vi commented 7 years ago

I might try to clarify using the grammar there.

Here's the relevant bit of grammar and explanation follows below.

 variable-list =  varspec *( "," varspec )
 varspec       =  varname [ modifier-level4 ]
 varname       =  varchar *( ["."] varchar )
 varchar       =  ALPHA / DIGIT / "_" / pct-encoded

variable-list says that you can have varspec multiple times deleimited by ,. This is a list of variable specifications.

varspec says that you can have varname followed by the modifier-level4 which is either :digits or *. This declares how you can specify variable with the extra bells and whistles like {var:20}

varname a.k.a. variable name says that you can have varchar multiple times and optionally there can be .. This is the name part from the above the var.

Finally the important part says that varchar a.k.a. character in the variable name varname can be only one of the following:

Hope that it sheds some light the topic.

mieszko4 commented 7 years ago

Thank you @w-vi ! I've actually read the specification from the beginning to realize the big picture of the URI templates and to actually understand the difference between URI templates and the actual URI :)

While we are on that, one interesting paragraph is (https://tools.ietf.org/html/rfc6570#section-2.3):

A varname MAY contain one or more pct-encoded triplets. These triplets are considered an essential part of the variable name and are not decoded during processing. A varname containing pct-encoded characters is not the same variable as a varname with those same characters decoded. Applications that provide URI Templates are expected to be consistent in their use of pct-encoding within variable names.

According to this paragraph, if I use {?%7eids} and %7eids := "value" I have to keep pct-encoded triplets, so I get ?%7eids=value.

Apiary, however, automatically changes such uri into ?~ids=value which according to this paragraph differs from ?%7eids=value. Chrome does it as well.

Is this according to the specification, am I missing something?

w-vi commented 7 years ago

Yeah, this is blurry, but I think that the pct-encoded means that when processing template you should not decode but when presenting the resulting URI you can. So filling the variables you need to keep the encoding but when you show it to the user you can decode.

mieszko4 commented 7 years ago

But does it mean then that user is allowed to enter the decoded character as a uri? In any case it seems chrome automatically decodes characters that are not reserved, which seems fine to me. I guess the specification is defined like that in order to be open for future extensions, ~ could be used for something. But, yeah it is a bit blurry.

I will close this issue now :)

w-vi commented 7 years ago

In URI ~ is definitely valid but in URI template as a template variable name you can't. There you can pct-encode it but the template processing, at the time where you create the URI from template it needs to be kept pct-encoded. It can then be decoded to give the final resulting URI. Does it make sense?

mieszko4 commented 7 years ago

Sure, thanx