Skip to content

Reconsider multiple basePath values #562

Closed

Description

@fehguy

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:

  • Often different hosts have different authorization mechanisms. If we re-introduce this feature, we'll need to support scoping authorizations to a particular host.
  • 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
  • The original support was intended for microservices, which is now better served by apis.json.

So this ticket gives some background and a recommendation for the next version. If there is strong objection, now is the time.

Activity

  1. fehguy commented on Feb 10, 2016

    @fehguy
    ContributorAuthor

    parent issue #560

  2. IvanGoncharov commented on Feb 10, 2016

    @IvanGoncharov
    Contributor

    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.

  3. fehguy commented on Feb 10, 2016

    @fehguy
    ContributorAuthor

    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.

  4. IvanGoncharov commented on Feb 10, 2016

    @IvanGoncharov
    Contributor

    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.

  5. webron commented on Feb 12, 2016

    @webron
    Member

    @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.

  6. IvanGoncharov commented on Feb 25, 2016

    @IvanGoncharov
    Contributor

    @webron I think we should distinguish two scenarios:

    • API owner want single point to describe multiply API which belong to his.
    • You have one logical API but due to performance concerns you move some of endpoint to separate hosts or basePaths. Upload/download is most widespread example.

    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.

  7. fehguy commented on Mar 14, 2016

    @fehguy
    ContributorAuthor

    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
  8. whitlockjc commented on Mar 14, 2016

    @whitlockjc
    Member

    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:

    • Is this a match for /pet/upload
    • Is this a match for /uploadMe/pet/upload
    • Is this a match for /uploadMe/pet/upload when the requested host is pets.com

    There 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.

  9. whitlockjc commented on Mar 14, 2016

    @whitlockjc
    Member

    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.

  10. whitlockjc commented on Mar 14, 2016

    @whitlockjc
    Member

    This might not be the proper place for that last comment.

  11. fehguy commented on Mar 14, 2016

    @fehguy
    ContributorAuthor

    @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.

    1. If schemes are defined in the operation, use it, otherwise, use the parent schemes
    2. If host is defined in the operations, use it, otherwise use the parent host
    3. If basePath is defined in the operation, use it, otherwise use the parent basePath

    I 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.

  12. whitlockjc commented on Mar 14, 2016

    @whitlockjc
    Member

    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.)

  13. fehguy commented on Mar 18, 2016

    @fehguy
    ContributorAuthor

    @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.

  14. november1306 commented on Jul 25, 2018

    @november1306

    creating separate spec document with code duplication if you have more than one subdomain is so stupid

  15. fehguy commented on Jul 25, 2018

    @fehguy
    ContributorAuthor

    Try to keep it cool, @november1306

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions