-
Notifications
You must be signed in to change notification settings - Fork 9.1k
Proposal for URI Template support #778
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
Comments
One side effect of having query parameters in the path string (i.e. level 3) is that it possibly allows having different operations for the same "resource" (i.e. path without query parameters), thereby solving parts of #164. (Doesn't mean I argue for this, just saying that it actually adds capability.) |
@ePaul Yeah, I've done something like |
If I may make a suggestion, I think its easier to think of a url as a path template as-is and not re-construct it from attributes on parameters (separators etc.). When you have a non-trivial set of parameters with each specifying separators they conflate the notion of templates into parameters. It is a concept thats at a higher level than a parameter, for e.g. take name and age as query parameters IMO I think it should work just like how templates work with path variables. Another benefit of doing it this way is also that it allows for unique paths that can be exercised independently rather that the work around today where you have one
The current solution is to model it this way
Plus this is already supported in springfox and here is the corresponding swagger-ui with RFC6570 support. I really don't think the levels really matter in general. However, the spec could specify a subset coming from a contract-first perspective for e.g. |
@dilipkrish To answer your question about the Yes, I agree we need to address the desire to have distinct resources that only differ by query parameters. For the longest time I was in agreement that pushing complete URI templates into the path was the correct solution. However, I no longer think so. I've spent quite a bit of time looking at API routing mechanisms and the most efficient solution is always to match the path first and then match query parameters as a distinct step. If you don't do that, then you end up with problems like failing to match when query parameters are provided in a different order than the definition. When you live in the hypermedia world, this doesn't happen, but in the rest of the world it does. I've been considering a solution that looks something like this... paths:
/customers:
get-by-email:
parameters:
email: ...
responses: ...
get-by-name:
parameters:
firstname: ...
lastname: ...
responses: ... The operation key now allows a Interestingly, in the tables you created to explain your scenario, you created a column called |
Its also to distinguish between forms continuation. e.g. constant/defaulted parameters
Url templates is a solved problem, at least it has a comprehensive test suite. Tactically tho' this can be solved by sorting the parameters when building the templates. For backwards compatibility with existing swagger endpoints and providing determinism in template expansion, what I've been doing is
While its essentially moving characters from part of the (OAI) object graph to another, its not the same thing IMHO. Im thinking of downstream possibilities that it opens up rather than just the ability to describe operations. To list a few reasons why I prefer not having that indirection,
|
Arguably we can already make that distinction because we have the
Only for going from template to URL instance, not the other way around. RFC 6570 explicitly calls this out
There is definitely an elegance to URI Templates (once you get past some of the weird operator syntax). However, I think it is easier for tools to glue things together than to split them apart. The code to create a URI Template out of the component pieces in an OpenAPI document is massively simpler than extracting parameter information from a URI Template. Allowing query parameter templates in the If a template indicates a query parameter is optional, but the parameter definition says the opposite, which wins? Do parsers need to detect that as a syntax error? And URI templates themselves are not without limitations. Parameter names cannot include hyphens without them be escaped. And there is no way to express an optional query parameter that should not be escaped. As an author of a URI Template library, I would love to see their use everywhere, but I'm not convinced that they are the best fit for the OpenAPI model. |
Wasn't what I was implying. Take this example of a HAL resource interaction. Curl
Response body {
"_links": {
"self": { "href": "/orders" },
"next": { "href": "/orders?page=2" },
"find": { "href": "/orders{?id}", "templated": true }
},
"_embedded": {
"orders": [{
"_links": {
"self": { "href": "/orders/123" },
"basket": { "href": "/baskets/98712" },
"customer": { "href": "/customers/7809" }
},
"total": 30.00,
"currency": "USD",
"status": "shipped",
},{
"_links": {
"self": { "href": "/orders/124" },
"basket": { "href": "/baskets/97213" },
"customer": { "href": "/customers/12369" }
},
"total": 20.00,
"currency": "USD",
"status": "processing"
}]
},
"currentlyProcessing": 14,
"shippedToday": 20
}
I will be convenient to lookup the definition of the Ofcourse the solution for #688 might make it simpler, but on its own, this solution would enable richer possibilities for downstream effects.
Don't follow what that means. Path already supports a template minus templates for query parameters. Are u suggesting URI templates with query strings in the template are no longer paths? Also, we're not trying to implement the uri templates exhaustively, an 80/20 solution would suffice IMO. Its not very different from OAI supporting json schema, but not every nuance it can describe. It goes back to your post about open vs closed world specification. |
This has been clarified by #804 |
This is a proposal to enable OpenAPI to support many of the features of URI Templates defined by RFC 6570, without adopting the URI Template syntax.
Overview
Open API already supports some of the URI Template capabilities but it does so with a simplified path template syntax and then parameter objects that describe the parameters.
In summary, the proposal is to add the following properties to the parameter object:
Below is a description of the URI Template features and how these new parameter properties would work.
Details
RFC 6570 defines four levels of support.
Level 1: /bar/{foo}/baz
Open API already supports Level 1 templates
Level 2: {[+|#]foo}
This level adds support for fragment parameters and unescaped parameter values.
By adding the
fragment
option to thein
property of the we could support fragment parameters. However, as fragment parameters are not sent from client to server, I'm not sure there is any value in adding this support.Adding an
escape
Boolean property to the parameter object would allow OpenAPI parameters to specify whether parameter values be escaped. This should be an optional property with a default oftrue
.Level 3: {[+|#|.|/|;|?|&]foo,bar}
This level adds a bunch of separator characters that are prefixed in front of the parameter value. By adding an optional
separator
property to the parameter object we can add this capability to OpenAPI. The value the?
and&
parameters are debatable because we already known which parameters are in the query string.The ability to have a list of parameter names in a var spec is just a syntax shortcut and I don't believe adds any capability that OpenAPI doesn't already have.
With a path like
an output path might be
Level 4: {[+|#|.|/|;|?|&]foo,bar[:n|*]]}
This level adds two suffix options and the support for values that are lists and maps. The
:n
suffix option that allows you to just take the first few characters off a parameter value seems unnecessary to me.The explode operator is useful if we accept supporting maps and lists as parameter values. Should
map
andlist
be added as two native parameter types? Adding anexplode
Boolean property to the parameter object would be sufficient to add this support.With this parameter and assuming the path defined in the level 3 example and a parameter value of ["red","green","blue"] then you would get:
Constraints
There are certain capabilities in URI Templates that make it difficult for tooling to do the types of things that users are used to doing with OpenAPI. In order to limit the pain, there are some constraints that might be worth adding to these new parameter object properties:
/
separator be allowed in path parameters?The text was updated successfully, but these errors were encountered: