This was one of those features that shipped with swagger 1.0, 1.1, and 1.2 but was removed in 2.0.
The current spec does _not_ allow multiple hosts to be defined _for execution_. You can host the spec in different pieces and across multiple hosts, but the execution shall be for a single host. That host is configurable in the spec, but it applies to _all_ operations.
There has been pushback on this from a number of people so I'd like to put it back out in the open. We _can_ reintroduce a construct for multiple hosts. Having gone through the pains of both implementing and supporting it in tools, I would strongly suggest we do not.
My reasoning:
http operation from a https-hosted page, for example) introduces show-stopping compatibility issues for web-based tools. Multiple hosts in a single spec will exacerbate this issueSo this ticket gives some background and a recommendation for the next version. If there is strong objection, now is the time.
parent issue #560
I think we should consider real life scenarios for this issue.
Most common is separate base paths for file uploads, for example in Google APIs
https://www.googleapis.com/drive/v3
https://www.googleapis.com/upload/drive/v3
https://www.googleapis.com/youtube/v3
https://www.googleapis.com/upload/youtube/v3
Or different subdomain:
https://uploady.com/v1/api/
https://content.uploady.com/v1/api/
https://api.dropboxapi.com/2
https://content.dropboxapi.com/2
I think RAML have pretty good solution for this problem:
https://github.com/raml-org/raml-spec/blob/master/raml-0.8.md#base-uri-parameters
And I think template parameters in host and basePath also needed for other things like separate subdomain for sandbox, allow to choose server location, etc.
Thanks @IvanGoncharov. Aside from ease of modeling, what do you think of three concerns I listed above? I don't think the hard part is how to model it, which RAML does, it's more about how you use it.
My main point here is that separate baseUrl for file upload/download is common pattern and it has performance reasoning behind it. So it will not disappears in nearest future and should be dealt with as first-class citizen in OpenAPI world. Also it don't require any special mechanism to handle just template parameters for host and basePath which already requested for other reasons #169
Often different hosts have different authorization mechanisms. If we re-introduce this feature, we'll need to support scoping authorizations to a particular host.
I'm also not like idea of putting two different APIs in one spec.
If they differ in something other than host or basePath it should be separate spec.
I think it's make a good borderline principle, but allow to handle most of real life scenarios.
The original support was intended for microservices, which is now better served by apis.json.
I'm totally against putting separate APIs into one Swagger file it's creating a total mess.
And I think if you ask people why they asked for such feature you will hear that it's file upload/download in most of the cases.
Moreover in my project I work with hundreds of different real-world APIs and I only had problems similar to the ones that I presented in my previous comment.
Spanning different protocols (calling a http operation from a https-hosted page, for example) introduces show-stopping compatibility issues for web-based tools. Multiple hosts in a single spec will exacerbate this issue
Can you provide more concrete example, because right now I don't see any problem?
I'm not a frontend developer so I can miss something obvious, but still it's better to explicitly describe possible problems.
@IvanGoncharov API design choices aside, it's difficult to discount the number of times we've been asked for a solution for multiple basePath support since we published 2.0. We had plans on introducing a solution to it (still have it somewhere) as an external extension, but we abandoned it partly due to lack of resources and partly because there's an alternative solution such as apis.json.
@webron I think we should distinguish two scenarios:
I agree that first should be solved by totally separate format.
But in second case you make API owner to create separate file with one method and moreover to duplicate all other info like definitions, parameters, info, tags, securityDefinitions, etc.
Here is my proposal for this:
Add support for multiple hosts by adding optional attributes at the path and operation level. When not present, the top-level settings will apply:
host: <host>
basePath: <basePath>
schemes:
- <scheme>
Path-level example:
paths:
/pet/upload:
host: https:/pets.com
basePath: /uploadMe
get:
operationId: theUsualStuff
Operation-level example:
paths:
/pet/upload:
host: https:/pets.com
basePath: /uploadMe
get:
host: https://pets.com
basePath: /uploadMe
operationId: theUsualStuff
I think from an API description authoring perspective, this just muddies the waters. Not only can I do the same by putting the basePath into the path key, /uploadMe/pet/upload but now I can do the same thing with a combination of path key and operation/path-level basePath? Not only that but from a tooling perspective, how does this get handled? To me, it seems like this singular path definition could potentially have three runtime checks:
/pet/upload/uploadMe/pet/upload/uploadMe/pet/upload when the requested host is pets.comThere could be more permutations but I have no idea what multiple base paths or per path/operation level base paths should be handled. What was once a singular view of your API is no longer the case. I have to do some computation just to figure out what this API looks like and that violates the human readability of the OpenAPI documents.
To me, when I have an API it is host/path agnostic. I write an API and whether I deploy it to QA, test, prod, ... my API looks and works the same. Now I realize based on the deployed environment that things like the hostname will obviously be different and that the base path could potentially be different but my API is still the same. The same operations will return the same objects and have the same contract.
All of this being said, I often wonder why these details are even in the OpenAPI documents at all.
This might not be the proper place for that last comment.
@whitlockjc there are no path permutations to worry about. This is only for the execution of an operation, and it would follow the same inheritance as, say, consumes.
schemes are defined in the operation, use it, otherwise, use the parent schemeshost is defined in the operations, use it, otherwise use the parent hostbasePath is defined in the operation, use it, otherwise use the parent basePathI don't think this is a modeling concern, more an operations concern. It allows a user to send a request to an alternate location which as @IvanGoncharov mentioned, can make sense.
I got you. That makes more sense now. Thanks for clarifying.
To me, this seems like a feature where you want to have a single OpenAPI document to sit in front of N different _real_ APIs. Is this a use case we want to support? For the APIs that share a common host name, to me that is a single API and you can easily support this with path patterns. _(The Google APIs examples from @IvanGoncharov.)_ For the APIs that do not share a common host, is it really even fair to treat them as the same API? _(The uploadly and dropbox examples from @IvanGoncharov.)_
@whitlockjc I get it--one could take this very far in the direction of having many hosts in one specification, we can't keep people from abusing the idea. But I do think it's worth supporting this construct. Tooling will be easy to handle it.
creating separate spec document with code duplication if you have more than one subdomain is so stupid
@november1306 https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#server-object-example
Try to keep it cool, @november1306
Most helpful comment
I think we should consider real life scenarios for this issue.
Most common is separate base paths for file uploads, for example in Google APIs
https://www.googleapis.com/drive/v3
https://www.googleapis.com/upload/drive/v3
https://www.googleapis.com/youtube/v3
https://www.googleapis.com/upload/youtube/v3
Or different subdomain:
https://uploady.com/v1/api/
https://content.uploady.com/v1/api/
https://api.dropboxapi.com/2
https://content.dropboxapi.com/2
I think RAML have pretty good solution for this problem:
https://github.com/raml-org/raml-spec/blob/master/raml-0.8.md#base-uri-parameters
And I think template parameters in
hostandbasePathalso needed for other things like separate subdomain for sandbox, allow to choose server location, etc.