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

Fix parsing of optional params in route #2209

Merged

Conversation

captainsafia
Copy link
Contributor

The current RelativePathSansQueryString method causes problems with the approach that minimal APIs use for setting an endpoint names.

With an endpoint like:

app.MapGet("/bar/{foo?}", (string foo) => ...);

Will produce a relativePath that looks something like /bar/{foo which is incorrect.

To mitigate this, I used a negative lookahead regular expression to only split on the query string part and to ignore optional parameters.

Regex.Split is not as performant as a string.Split but I wasn't sure what other alternatives might be best here.

Is there a particular reason that we remove the query string part? There might be another alternative to approach here (e.g. removing the query string with the existing strategy in another codepath).

@domaindrivendev
Copy link
Owner

domaindrivendev commented Sep 3, 2021

@captainsafia this extension method was carried over when I ported the original WebApi version to Core. It's used to obtain the corresponding OpenAPI "path" for an operation and removes the query part because OpenAPI does not allow query strings in the "path":

Query string parameters must not be included in paths. They should be defined as query parameters instead.

With that said though, I'm wondering if the extension is required anymore because I don't believeApiDescription.RelativePath can ever have a query part in it in the first place. At least for controller/action routing, I don't think you can define a route template with a query parameter in it (e.g. [HttpGet("/resource?foo={bar}")]. For minimal APIs though I'm not sure.

Perhaps you could confirm for both cases? And, if it's not possible in either, I think we can just remove the extension method and revert to using ApiDescription.RelativePath instead.

@domaindrivendev domaindrivendev added this to the vNext milestone Sep 3, 2021
@captainsafia
Copy link
Contributor Author

At least for controller/action routing, I don't think you can define a route template with a query parameter in it (e.g. [HttpGet("/resource?foo={bar}")]. For minimal APIs though I'm not sure.

Query params aren't supported in route templates, only route segment parameters. It's expected that users will use parameters on the action or a FromQuery attribute.

Given this, I can update the PR to remove the use of the extension method.

@@ -48,6 +48,37 @@ public void GetSwagger_GeneratesSwaggerDocument_ForApiDescriptionsWithMatchingGr
Assert.Equal(new[] { OperationType.Post, OperationType.Get }, document.Paths["/resource"].Operations.Keys);
}

[Fact]
public void GetSwagger_GeneratesSwaggerDocument_ForApiDescriptionsWithVariousRelativePaths()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the change, I'm not sure this test has much value anymore as it's all just based on direct assignment of the RelativePath property surfaced by API Explorer. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not really necessary but I left it in to future-proof. As far as I can tell, it's the only test that validates with optional route params so it gives us coverage for this area in the event of any issues in the future.

@domaindrivendev domaindrivendev merged commit 2f5db3a into domaindrivendev:master Sep 8, 2021
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

Successfully merging this pull request may close these issues.

2 participants