Optional and multi-segment path parameters
See original GitHub issueThis is a meta issue representing a number of requests over the years including #1459 #1840 #892
Currently the OpenAPI specification does not allow optional path parameters nor path parameter values that allow characters such as the /
. This means that if you had the following API description:
/myfiles/{mypath}/{filename}:
parameters:
- name: mypath
type: string
- name: filename
type: string
then you would not be allowed to have myPath = “a/path/to/a/file” unless you escaped the forward slash character.
Also, the RFC6570 URI Template /myreports/{reportName}{/nonDefaultFormat}
where the last path segment is optional is not supported by OAS.
The primary reason for not supporting these types of APIs is that it creates the potential of an ambiguous match between a URL and the corresponding path item. Some tooling depends on being able to identify the API description for a specific URL. If multiple pathItems match, then some kind of alternate selection algorithm must be defined.
There have been a number of suggestions on how that selection algorithm might work, with varying levels of complexity. The open question is if there is enough community demand to justify the work necessary to find an acceptable solution.
If you have real-world scenarios where adding support for either multi-segment path parameters or optional path segments would make your life easier, please share them in this issue.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:7
- Comments:22 (3 by maintainers)
Top GitHub Comments
I propose to add support of
{+path}
expression from RFC6570. Please vote on this if you agree!uri-template-router tries to invent a general algorithm for reversing a URI Template and it is, indeed, somewhat complicated, in large part because URI Template isn’t designed for matching.
The first rule I try to follow is a simple, self-evident principle: If X is a strict subset of Y, then match X before Y.
This means that
http://example.com/a/b/
will match templates in the following order:http://example.com/a/{+foo}/
andhttp://example.com/{+foo}/b/
http://example.com/{a}/{b}/
(requires exactly three slash characters in the path)http://example.com/{+a}/{+b}/
(requires at least three slash characters in the path)http://example.com/{+foo}/
(requires at least two slash characters in the path)http://example.com/{+foo}
(the biggest set)Then for picking between disjoint URI templates, prefer templates that are strict subsets when only looking at the first characters. Therefore,
http://example.com/a/{+foo}/
would be matched first because if you compare only the first 20 characters of matching URIs,http://example.com/a
is a strict subset ofhttp://example.com/{+foo}
(where{+foo}
matches zero-or-one characters).Finally, I match empty strings by default. Because URI Template isn’t a matching syntax (like regexp), it doesn’t have a way for requiring a minimum number of matches. Developers requiring a match are expected to validate the values for the matches, and call
Result#next
if one of the variables is invalid (e.g. is empty, when a minimum of 1 character is expected).I recall there being one or two small bugs with the algorithm that I have, I was in the process of mathematically trying to prove that an algorithm implementing all these requirements is computationally possible, and then got sidetracked.