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

Allowing hyphens in Query Params #460

Closed
c0 opened this issue Apr 21, 2016 · 12 comments
Closed

Allowing hyphens in Query Params #460

c0 opened this issue Apr 21, 2016 · 12 comments
Labels

Comments

@c0
Copy link

c0 commented Apr 21, 2016

I have a query param that has a hyphen as the key. e.g. foo-bar, but dredd is throwing an error that it's invalid.

For example:

## Things [/things{?widget-type}]

+ Parameters

      + `widget-type`: wonky (string)

But when I run dredd, I get:

error: Runtime compilation error:
 Failed to parse URI template: /things{?widget-type}
 Error: SyntaxError: Expected "(", "*", ",", ":", "}" or [a-zA-Z0-9_.%] but "-" found.
 on  > Things > widget-type
error: Error parsing ast to blueprint.

I haven't see any specs that prohibit -

Looks like the source is grncdr/uri-template#14

@honzajavorek
Copy link
Contributor

@c0 This might be a bug. Some special characters may cause problems due to Markdown nature of API Blueprint (e.g. underscore, which invokes italics), but escaping them with backticks should work 😐

@smizell
Copy link
Contributor

smizell commented May 10, 2016

I did a quick check and found the issue was in the URI template and not the parameters (as @c0 linked to). The following blueprint gives this same compilation error and warning.

FORMAT: 1A

# Hyphen Test

## Foo Bar [/{foo-bar}]
### GET
+ Response 200

@honzajavorek Please also note the issue referenced by by @c0, saying that according to the spec, hyphens are not allowed.

@c0
Copy link
Author

c0 commented May 10, 2016

Yes, it's not in the URI Template spec. I just find it odd that we can't document URIs with hyphens (which is a valid URI character).

Thoughts about moving away from the spec?

@smizell
Copy link
Contributor

smizell commented May 10, 2016

I believe you are able document URIs with hyphens, however you cannot use hyphens within URI template parameters. In other words, /foo-bar{?baz} is valid while /{foo-bar} is not. I just verified this.

@smizell
Copy link
Contributor

smizell commented May 10, 2016

However, we'd love to hear your use case here. :) Do you have any requirements pushing you toward using hyphens for parameters?

@c0
Copy link
Author

c0 commented May 10, 2016

Here's our use case:

  • API endpoints enforce versioning and the Accept header is preferred.
  • As an alternative, a dev can append ?api-version=#, which is very useful for debugging.

I'm adding dredd tests for both scenarios.

@smizell
Copy link
Contributor

smizell commented May 10, 2016

Oh, I see here, as the issue with the query string since it is both the query parameter name and the URI parameter name. That makes sense. :) Thank you for sharing.

@smizell
Copy link
Contributor

smizell commented May 11, 2016

@c0 I've done a little more research here. The issue is actually in the blueprint parser, so I believe we can close this for now from a Dredd perspective. I found this comment, and thought even though it is a couple of years old, maybe it can give you a glimpse into the opinion on RFC6570 :) I'd encourage you to bring up your desires on the blueprint repo if you are interested in pursuing this issue there.

However, I've opened another Dredd issue #481 that is really a superset of this issue you've opened. Maybe the solution there would allow you to use hyphens in the short term? If your server decodes anything that is URL encoded, maybe it will actually work for you now without any changes to Dredd. Please let us know on that PR if that is a helpful solution.

And thanks for opening this issue. Please continue to bring these things to our attention in the future, even if you think they are small things :)

@smizell smizell closed this as completed May 11, 2016
@T0nyACr0ntum
Copy link

T0nyACr0ntum commented Aug 4, 2017

Hi there. I have a weird issue concering hyphens.
When my blueprint contains a key-value pair with an underscore in key and value, it expects an additional object due to a wrong interpretation.
Here is the Request from my blueprint:

  • Request (application/json)

    • Attributes
      • id: 2 (number)
      • q_number: ACT0002 (string)
      • role_name: hq_calendar_reader (string) <<< this is where the error appears
      • markets: [1] (array)
      • activated: true (boolean)
      • isDeleted: false (boolean)

And the actual output:
body:
{
"id": 2,
"q_number": "ACT0002",
"role_name: hq_calendar_reader": "",
"markets": [
"[1]"
],
"activated": true,
"isDeleted": false
}

As you can see the role_name: hq_calendar_reader expects another value.
This is somehow caused by the underscore.

Fun fact: When I remove the underscores either on key side or value side it's interpreted right.
So

  • rolename: hq_calendar_reader (string)
  • role_name: hqcalendarreader (string)

would be interpreted right
body:
{
"id": 2,
"q_number": "ACT0002",
"rolename": "hq_calendar_reader",
"markets": [
"[1]"
],
"activated": true,
"isDeleted": false
}

body:
{
"id": 2,
"q_number": "ACT0002",
"role_name": "hqcalendarreader",
"markets": [
"[1]"
],
"activated": true,
"isDeleted": false
}

@honzajavorek
Copy link
Contributor

@T0nyACr0ntum That's because API Blueprint is based on Markdown and in Markdown the underscores have a special meaning. You can escape the name of the attribute as well:

+ Request (application/json)
    + Attributes
        + id: 2 (number)
        + q_number: ACT0002 (string)
        + `role_name`: `hq_calendar_reader` (string)
        + markets: [1] (array)
        + activated: true (boolean)
        + isDeleted: false (boolean)

@T0nyACr0ntum
Copy link

@honzajavorek Thanks, for the help... I just tried to escape the value but not the key.
Escaping on both sides works fine!

@armen-ch
Copy link

armen-ch commented Apr 8, 2022

Sorry for activating this long ago closed discussion but it's really important for integrating Dredd into our api validation process. We have dozens of microservices which have parameters which contain hyphens in their names and we can't use Dredd because of this limitation. Btw swagger editor normally accepts those apis as completely valid schemas (screenshot is attached).
I did some research and came across different articles in the internet which declare hyphen as a valid query parameter character and looks like it's widely used, e.g.
https://en.wikipedia.org/wiki/Query_string
https://developers.google.com/maps/url-encoding https://www.oreilly.com/library/view/restful-web-services/9780596809140/ch04.html
https://stackoverflow.com/questions/32348875/can-hyphens-be-used-in-query-string-values
https://datatracker.ietf.org/doc/html/rfc3986#section-2.3

Moreover it is highly encouraged to use hyphens instead of underscores when designing URI : https://developers.google.com/search/docs/advanced/guidelines/url-structure#:~:text=We%20recommend%20that%20you%20use,(%20_%20)%20in%20your%20URLs

I understand that you are trying to stick with rfc6570 but probably few follow the rules. Is it possible to replace this exception with warning? Or may be add some option/config to switch between interpretation of this rule as warning or error?

param-with-hyphen

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

No branches or pull requests

5 participants