Skip to content

Support API mounting #2854

Closed
Closed

Description

@MaxenceMaire

This follows a comment on issue #647.

It would be great to be able to mount API specs onto another spec for service composition.

As an example, I have two independent services A and B, both having their own OAS files. I would like to 'merge' A and B together into a single, centralized spec.

If both services have, say, a /resource endpoint, I would like to discriminate them by prefixing their paths with the name of the services, /A and /B respectively (resulting in /A/resource and /B/resource).

One naive solution would be to list and redefine each path in the root OAS file and $ref the related A or B content, but changing the design of either A or B would require updating the root OAS file.

A possible alternative would be to support path nesting (discarded here):

paths:
  '/A':
    '/resource':
       get:
           # ....
  '/B':
    '/resource':
       get:
           # ....

I suggest considering introducing a mount field under Path Item Objects and taking a Paths Object:

paths:
  '/A':
    mount:
      $ref: 'A.yaml#/paths'
  '/B':
    mount:
      $ref: 'B.yaml#/paths'

Activity

  1. SmallhillCZ commented on Feb 15, 2022

    @SmallhillCZ

    I have the same use case, but I would rather show in some way, that under this path there is another API with its own spec and so I would rather reference not the paths included in its OAS, but the full OAS file. So more like a link to another API than a $ref.

  2. nickshoe commented on Feb 17, 2022

    @nickshoe

    Another possibility could be to allow multiple $ref right under paths:

    ...
    info: ...
    tags: ...
    ...
    paths:
      $ref: './service-a.yaml#/paths'
      $ref: './service-b.yaml#/paths'

    Assuming that the content of the referenced file is the following:

    # service-a.yaml
    ...
    paths:
      '/service-a/foo':
        ...
    # service-b.yaml
    ...
    paths:
      '/service-b/bar':
        ...

    The root spec content would finally be rendered as:

    ...
    info: ...
    tags: ...
    ...
    paths:
      '/service-a/foo':
        ...
      '/service-b/bar':
        ...

    Is this simplistic? I know that the current spec doesn't allow it, am I missing some hidden aspect about why it shouldn't be done this way in the first place?

  3. MaxenceMaire commented on Feb 28, 2022

    @MaxenceMaire
    Author

    I have the same use case, but I would rather show in some way, that under this path there is another API with its own spec and so I would rather reference not the paths included in its OAS, but the full OAS file. So more like a link to another API than a $ref.

    @SmallhillCZ You make a good point. Especially since mounted APIs can live on different servers (or to specify useful metadata), I think it makes sense to include a complete OAS and not just the paths. A $ref could still work though I guess? (e.g. $ref: 'A.yaml' instead of $ref: 'A.yaml#/paths').

  4. MaxenceMaire commented on Feb 28, 2022

    @MaxenceMaire
    Author

    Another possibility could be to allow multiple $ref right under paths:

    ...
    info: ...
    tags: ...
    ...
    paths:
      $ref: './service-a.yaml#/paths'
      $ref: './service-b.yaml#/paths'

    Assuming that the content of the referenced file is the following:

    # service-a.yaml
    ...
    paths:
      '/service-a/foo':
        ...
    # service-b.yaml
    ...
    paths:
      '/service-b/bar':
        ...

    The root spec content would finally be rendered as:

    ...
    info: ...
    tags: ...
    ...
    paths:
      '/service-a/foo':
        ...
      '/service-b/bar':
        ...

    Is this simplistic? I know that the current spec doesn't allow it, am I missing some hidden aspect about why it shouldn't be done this way in the first place?

    @nickshoe As you noted, the spec says the following about this:

    Any sibling elements of a $ref are ignored. This is because $ref works by replacing itself and everything on its level with the definition it is pointing at.

    Meaning only one $ref is evaluated (hence the idea of a new property). Replacing paths with a list (instead of an object) would allow for multiple $ref, although it would also permit listing identical Path Item Objects multiple times (which I think is why paths is an object in the first place).

  5. nickshoe commented on Mar 2, 2022

    @nickshoe

    @MaxenceMaire thanks for clarifying the use of $ref.

    My example was an alternative proposal. Anyways, I like your proposal too (I've put a thumbs up).

    We ended up defining separate OpenAPI documents for each microservice and using them independently. It would be nice to be able to squash together separate specs, without having to break them down according to the root keys of the spec. If conflicts arise, then one should handle them by changing one of the sub-specs.

  6. gimbimloki commented on Mar 7, 2023

    @gimbimloki

    @nickshoe @MaxenceMaire

    I asked "Reference Objects in Paths Object".
    As a rsult, it is duplicated keys and it is not allowed in YAML/JSON.
    I think we should find another? altinative? way(add new field, list and something... ).

  7. added
    Moved to MoonwalkIssues that can be closed or migrated as being addressed in Moonwalk
    on Jan 27, 2024
  8. handrews commented on Jan 27, 2024

    @handrews
    Member

    I believe this is addressed by OAS 4 Moonwalk's separation of concerns principle. Specifically:

    I'm going to close this as "moved to moonwalk", but please join the linked discussion if you are still interested!

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

    Moved to MoonwalkIssues that can be closed or migrated as being addressed in Moonwalk

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions