OAI / OpenAPI-Specification

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

Why don't host and basePath support path templating? #169

Closed maxlinc closed 7 years ago

maxlinc commented 10 years ago

The Swagger 2 schema says that neither host nor basePath support path templating. We probalby discussed this but I don't remember the exact reason and it seems like a big limitation. It's common to have parameters in either the host or in the basePath. You can at least work around the basePath limitation with excessively long paths, but there is no workaround for parameter in a host. Swagger will force you to hardcode a value.

Real-world examples:

I think the reason may have been just:

It's also worth noting that neither host nor basePath are required, nor are they required to resolve to the actual API (e.g. you could set your host to example.com).

I'm hoping to at least get support targeted for the next spec, if not an update to this spec clarifying that host/basePath templating is not required but may be supported by some projects.

Jasontang501 commented 9 years ago

Echo on what maxlinc said above, provide support for parameter in a host will be great as this is a big blocker for us to adapt Swagger in our current projects.

mohsen1 commented 9 years ago

What happens if an operation has a path parameter which is the exact same name of this proposed global path parameter in basePath?

How the tooling can decide which value goes to which parameter?

Here is an example:

---
swagger: '2.0'
info:
  version: 1.0.0
  title: Pets Store

basePath: /{name}/
paths:
  /{name}:
    get:
      parameters:
        - name: name
          in: path
          description: name
          type: string

      responses:
        200:
          description: Returns all the pets
maxlinc commented 9 years ago

@mohsen1 You raise an interesting question about a case where the spec is probably ambiguous, but not something that worries me about basePath in particular. The basePath allows you to write DRY swagger, but it can always be written in a more redundant, expanded form without a basePath. And those cases are equally ambiguous.

Your example should be the equivalent of:

---
swagger: '2.0'
info:
  version: 1.0.0
  title: Pets Store

paths:
  /{name}/{name}:
    get:
      parameters:
        - name: name
          in: path
          description: name
          type: string

      responses:
        200:
          description: Returns all the pets

Here's a more realistic example:

paths:
  /users/{name}/friends/{name}

That's ambiguous. You shouldn't use the same variable name if you're talking about two different variables. This doesn't just confuse Swagger, it would confuse most client and server-side APIs that do parameter expansion or extraction.

For example, it would be equally bad as a rails route:

get '/users/:name/friends/:name', to: 'friends#get', as: 'friend'

And similarly, I don't think scoping makes it less ambiguous:

scope 'users/:name' do
  get 'friends/:name', to: 'friends#get', as: 'friend'
end

So basically: same name => same variable => same value substitution. If you don't want that than you should use distinct names:

paths:
  /users/{user_name}/friends/{friend_name}
theage commented 9 years ago

Voting for this.

@mohsen1 & @maxlinc, while it is maybe not good practice to reference the same parameter multiple times in basePath and a path item, it should not matter though, because unlike a server route binding, code using a Swagger definition works the other way round: It substitutes a parameter reference with a value rather than extracts it, and validation should also be trivially possible, at least in theory. But even if not, one could still produce an error when encountering a conflict.

It could only be a problem if you had multiple definitions for the same parameter, but this is resolved by using the most specific definition already.

zenexius commented 9 years ago

Plus one for this feature. I came across a situation where region and language are part of the base path Something like

https://myserver.com/{region}/{lang}/products

Now if I don't use the base path then for each end point I have to use

/{region}/{lang}/products /{region}/{lang}/users ... and so on

You got the idea

samitpatel commented 9 years ago

+1

It would be great to have templating support for host so that we don't have to have multiple swagger definitions for development, test and production environment which uses different host.

Thanks.

mm-gmbd commented 8 years ago

+1

Really a big need (for me). I'm importing my swagger into Postman, and it doesn't interpret the path parameter (that is a part of the basePath in my swagger) as a variable. My current workaround is to change the swagger to basePath: {{varName}} so that Postman interprets it correctly, but I'd like to just wrap it with one set of curly braces for consistency.

Also, I understand that there will have to be work done on the Postman side for detecting that as a parameter path and ensuring that it is twice-wrapped with curly braces, but having it be officially supported in the Swagger spec would be the first step.

cabbonizio commented 8 years ago

+1

I created the issue in the swagger-ui area but was asked to +1 this one. This functionality would be very useful for us.

whitlockjc commented 8 years ago

This is a tooling issue in my opinion. If you need to do preprocessing of your Swagger document, why does Swagger care how you do it? This is my first impression on the matter. If my opinion changes after reading the information above, I'll comment again.

rglowzenski commented 8 years ago

+1

jcunningham77 commented 8 years ago

+1

mkrufky commented 8 years ago

+1

gobengo commented 8 years ago

+1 we could really use hostname parameterization!

cabbonizio commented 8 years ago

It would nice nice to somehow incorporate the use of "environments" to the spec (dev, int, qa, prod, etc.) and a hostname for each one. Prior to selecting the "Try it out!" button, you can select an environment to invoke the API. The use of Swagger right now just limits to a single host and would be nice to have one place to go to discover API documentation and test against any environment.

webron commented 8 years ago

@cabbonizio - well, there is a solution to that. As long as the spec is hosted in each environment, you can drop the host altogether, and the 'hosting' host will be assumed. I think leaking into environment management inside the spec itself is somewhat out of scope.

cabbonizio commented 8 years ago

Fair enough @webron. Is the concept of hostname parameterization still on the table at least?

webron commented 8 years ago

Anything that's labeled as OpenAPI.Next Proposal is on the table.

cabbonizio commented 8 years ago

good to know...thx for the info @webron. Looks like there's a decent number of votes.

lieldulev commented 8 years ago

Another vote here :) +1

ChiefORZ commented 8 years ago

:+1:

pradeep122 commented 8 years ago

:+1:

cabbonizio commented 8 years ago

In the meantime, I used a little markdown magic to provide clients of my services a grid letting them know each environment and host. If you drop this into the info.description field in the Swagger 2.0 spec it renders very nicely in Swagger UI and Editor just pushes your operations down a bit. It doesn't help with the test harness but it works for documentation purposes. Make sure you put a pipe character prior to the below.

  ### Host Mapping By Environment  

  | Environment | Network Zone | Host                      |
  |-------------|--------------|---------------------------|
  | Production  | Internal     | sample.host.com
  | Production  | External     | sample.host.com
  | QA          | Internal     | sample.host.com
  | QA          | External     | sample.host.com
  | INT         | Internal     | sample.host.com
  | INT         | External     | sample.host.com
fehguy commented 8 years ago

parent issue #574

kmceachern commented 8 years ago

👍 We'd like to provide access to Swagger UI both via a reverse proxy and by directly connecting to the host.

talolierwork commented 8 years ago

+1

xeranic commented 8 years ago

+1

fesaab commented 8 years ago

+1

lucbelliveau commented 8 years ago

+1

n-sviridenko commented 8 years ago

+1

lcrabb commented 8 years ago

+1 allowing for variable substitution from the request or response for the host name. similar to #742

webron commented 7 years ago

The introduction of the Server Object (instead of scheme, host and basePath) with Server Variables covers this now.

olebedev commented 7 years ago

@webron, could you please give the link to it ^ ?

darrelmiller commented 7 years ago

@olebedev https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/3.0.md#serverObject

Download commented 7 years ago

Can this be used for authorization url as well? See https://github.com/swagger-api/swagger-ui/pull/3410