OAI / OpenAPI-Specification

The OpenAPI Specification Repository
https://openapis.org
Apache License 2.0
29k stars 9.07k forks source link

3.1 Request - allowReserved in path #1840

Closed pepjo closed 9 months ago

pepjo commented 5 years ago

I have a use case where I have some type of "file system", the api works the following way:

/api/user/{id}/{+path_to_file}

where path_to_file is the actual path to the file.

The problem is that there is no current way to describe this with OpenAPI 3.0.

There is an option called allowReserved that would allow this but only work on query parameters. Why limit the option?

It is easy to see how it would work for the last path parameter, but I think it could work for any of them, it would match any character until the path matches the next part of the template.

darrelmiller commented 5 years ago

It is specifically disallowed on path parameters for the same reason we don't allow optional path parameters, e.g. {/foo} By having variable path segments it become difficult to resolve a URL to an operation. There can be a situation where an URL might map to many operations. We are considering introducing a priority property to help routing tools determine which operation to match. This is a conversation that will likely come up in one of our TSC meetings in the next few weeks.

yuchenshi commented 4 years ago

Any updates?

2is10 commented 4 years ago

Note: There is a lot of relevant prior art here. RFC 6570: URI Template Section 1.2 defines levels for template capabilities. Level 1 is very basic.

Level 2 templates add the plus ("+") operator, for expansion of values that are allowed to include reserved URI characters.

An example:

Expression: {+path}/here Expansion: /foo/bar/here

The Github REST API is a notable example of an API that uses this capability for accessing files in repositories. The Hypermedia section of their REST API documentation references RFC 6570. Here it is in action in an excerpt from one of their API responses: "contents_url": "https://api.github.com/repos/2is10/jshint/contents/{+path}"

That RFC is of course intended for URI expansion, not matching. But Github must have implemented matching internally.

My server background is primarily in Java, so I’ll speak briefly to that ecosystem. I’m confident that my observations generalize to libraries and frameworks in other languages. The two most popular ways to define REST APIs in Java, I think, are using 1) JAX-RS annotations or 2) Spring Web MVC annotations.

JAX-RS 2.1 supports matching multiple path segments per path variable using a regular expression such as this example from Section 3.4 URI Template of the spec:

@Path("widgets/{path:.+}") ... will be matched for any request whose path starts with widgets and contains at least one more path segment; the value of the path parameter will be the request path following widgets. E.g. given the request path widgets/small/a the value of path would be small/a.

Section 3.7 Matching Requests to Resource Methods details the somewhat technical but logical matching algorithm used to avoid the need for API authors to manually prioritize API operations. JAX-RS 2.1 has many implementations, including ones by Oracle, IBM, Google, and the Apache Foundation.

Spring Web MVC and Spring Web Flux (the newer async alternative to Web MVC) support .../** and .../{*path} as ways to match multiple path segments at the end of a path template. The Pattern Comparison section describes its matching algorithm (much simpler than the JAX-RS 2.1 one), which also avoids the need for API authors to manually prioritize API operations.

I hope this capability can make it into OpenAPI specifications. Limiting the capability to the end of a path would probably be much easier to achieve and would suffice for >90% of use cases, I imagine.

cb-Bhuvana commented 4 years ago

any updates on this?

ashutosh-sharma commented 3 years ago

Any updates on this?

handrews commented 9 months ago

This has been rolled up into #2653, which in turn will almost certainly be moved over to the Moonwalk (OAS 4) project, which as currently proposed supports full RFC 6570 URI Templates.