Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: $ref for Operation Object #2922

Closed
fcasad opened this issue Apr 29, 2022 · 18 comments
Closed

Feature Request: $ref for Operation Object #2922

fcasad opened this issue Apr 29, 2022 · 18 comments
Labels
re-use: ref-everywhere Requests to support referencing in more / all places

Comments

@fcasad
Copy link

fcasad commented Apr 29, 2022

The current OAS 3.1 spec allows the use of $ref for "Path Item Object" but not for "Operation Object". Is there a reason for this? It would be quite nice to be able to break down a large doc at the operation level. This could also be useful for describing APIs that are composed together (ie describing an API gateway).

@cebe
Copy link
Contributor

cebe commented May 2, 2022

If I understand your request correctly you could already do that, like this:

paths:
 '/path1':
    get:
      '$ref': 'operations/path1-get.yaml'
    post:
      '$ref': 'operations/path1-post.yaml'

# ....

edit: the above example would probably work with most of the tooling. However Reference is not explicitly listed as the Type for an operation here: https://spec.openapis.org/oas/v3.1.0#path-item-object so that is what should be updated.

@fcasad
Copy link
Author

fcasad commented May 2, 2022

Yep, that is exactly what I want to do.
It does work with the tooling I'm using, but my team was concerned since this isn't mentioned in the spec.

@webron
Copy link
Member

webron commented May 2, 2022

It's not currently supported by the spec, and @cebe's example is unfortunately invalid.

@fcasad
Copy link
Author

fcasad commented May 2, 2022

@webron thanks. Are you aware of any technical reasoning against supporting this? And if not, what would it take to add to the spec?

@webron
Copy link
Member

webron commented May 2, 2022

We try to be specific about what can be referenced as (especially now), we now include anything that can be referenced under components as reusable items.

Individual operations don't tend to be reused, and as far as I recall, we haven't had too many requests for it. Since operations tend to be specific to their path, describing methods such as GET, POST, PUT often accept/return entities that are specific to their paths - and reusing those just isn't all that common. Perhaps in the future if we support a more extensive level of reference templating, it would make more sense. Until then, I'm not convinced there's a good use case for adding support for it.

@fcasad
Copy link
Author

fcasad commented May 2, 2022

Appreciate the insight!

I agree a potential #/components/operations is probably not particularly helpful for reuse, but by that token is #/components/pathItems?

Btw, my goal isn't to reuse an operation within the same OAS document, but to split up a large doc into multiple files at the operation level. And also potentially ref those operations into other docs. I can resolve the refs at build time using something like this, which will produce a valid spec in the end. Would this be the preferred approach for my use case?

@webron
Copy link
Member

webron commented May 2, 2022

The reuse of Path Item Object was introduced a while back, and taking it out now is a bit of a challenge. I was surprised to see it being used, but it really is. You can argue and say that if we support one, we should support the other, which is completely fair. That said, we're trying to be conscious about adding additional complexity to the spec. For your use case, I'd say that splitting path items into separate files could give you at least some level of ability to split up large docs as a single path item object can have a finite number of operations.

You can definitely do your own magic with pre/post-processing docs, as long as the final doc is valid (you wouldn't be the first). Specifically the usage of $refs with the suggested dereferencer may or may not work. Reasons are: an OpenAPI definition is not a json schema, and OAS references are not exactly JSON Schema references (though for your own preprocessing, you can decide them to be whatever you want as they are out of scope for the spec).

@fcasad
Copy link
Author

fcasad commented May 2, 2022

Ok, it's understandable to try and avoid increasing the spec surface area. But splitting at the path item level isn't really ideal to me. I'll consider alternatives...

@mikky-is
Copy link

mikky-is commented Jul 7, 2022

Hello,
I have another similar case for the sake of completeness:
On RESTful APIs, the method OPTION should be available on every paths and thus would require to copy/paste a lot in the OpenAPI document.
However, except in case of required authentication/authorization, even me don't really see it useful to describe it in OpenAPI...

@adrianwebb
Copy link

Hello @webron, I would like to ask that this feature be reconsidered as well, and I think not having this feature is a serious oversight as I'll explain below.

Right now it is the case that Path objects are able to be replaced with a reference even though they are not "reusable", so I suggest that the aim of the references not be reusability so much as splitting up larger OpenAPI specification documents into more manageable chunks. This includes the reusability you speak of, because the objectives are the same (shorten the doc). If path objects can be referenced it makes no sense that operations can not be, since these are normally tied to different API endpoints on the backend. In fact operations make a lot more sense than the path being able to be referenced for this very reason. Trying to lump the external link generation for combined GET and POST operations requires literally creating a new backend API endpoint that returns a composite group of service specs around a base path. Since the operation is the base unit of the API endpoint, it actually makes more sense to have an operation ref than a path ref.

I have a use case where I have several endpoints for every data type that use the same filters (a huge number of them) and putting them in the same file as the top level specification causes timeout issues in the main file. I was looking for a way to move the filter parameters out of the top level specification, but the capabilities are not there. You can't reference parameter groups, just individual parameters, which doesn't help at all. So there is simply no way that I can see to accomplish what I need to do with the specification as it stands now.

What I wanted to do was to have is either parameter group references (not supported) or a query parameter on each of the filter supporting endpoints (?schema) that would render the schema for that API endpoint (in this case Django Views) then link to that reference in the top level file so that the top level file would be a lot more concise, and you could technically follow the references for path operations that you needed, seeing as how people are focused on designing for the endpoints, not the path objects.

If there is another way to achieve what I am trying to do please let me know? If what I expect is the case and there is no way to actually shorten this file without substantial changes to the backend endpoints then this should be a priority. It is one thing to argue against a feature if there is another way that is more canonical, but quite another when there is no other way to achieve the objectives in an efficient way.

@djMax
Copy link

djMax commented Oct 17, 2022

A huge part of the value of OpenAPI is not repeating yourself. We generate clients, servers, docs... all that with a simple and fairly conceptually tight format. But having a large interface split across several files now requires that you repeat each path in the top level specification file. This is super bad. Requiring extra tooling doesn't make it better.

@fcasad
Copy link
Author

fcasad commented Oct 17, 2022

Re-visiting since a few other folks asked for this...

I've now seen several large OpenAPI documents in the wild that have made this (non-canonical) use of $ref. One public example is Box, see here. @webron any chance it might still be considered?

@handrews
Copy link
Member

handrews commented Nov 6, 2022

Folks interested in this issue may be interested in the more general discussion of referencing that is now just getting started.

@vbauer
Copy link

vbauer commented Dec 29, 2022

We are interested in the same issue, any news?

jerstlouis referenced this issue in opengeospatial/ogcapi-processes May 31, 2023
Add short documentation on how to generate the desired files.

Small fix to make operationId unique
@aminabromand
Copy link

aminabromand commented Aug 27, 2023

What about this:

paths:
  /path1:
    $ref: "file1.yaml#/paths/%2Fpath1"
  /path2:
    $ref: "file2.yaml#/paths/%2Fpath2"

it is working. But is it allowed as per the Spec ?

[EDIT]: ok I recognized with openapi: "3.0.3" it works. With openapi: "3.1.3" it is not. :(

@handrews
Copy link
Member

@aminabromand

[EDIT]: ok I recognized with openapi: "3.0.3" it works. With openapi: "3.1.3" it is not. :(

This is likely to be a tooling issue you should open with your tool vendor, as the spec is the same in both versions in this regard.

@handrews
Copy link
Member

@vbauer there is talk of completely re-doing the referencing model in OpenAPI 4 (a.k.a. "Moonwalk") - here's a summary of the discussion from our last call before the late-summer break. With added opinionating from me.

As far as currently, since (unlike everywhere else), "$ref" in a path item object can combine with adjacent fields as long as the same field is not both adjacent to the "$ref" and in the target, you can sort-of re-use operations by making path items with one operation each and then "$ref"-ing them together. Which gets a little complex because you can only have one "$ref" per path item object so you'd kind of have to layer the on one at a time, but it could be done. I think.

@handrews handrews added $ref re-use: ref-everywhere Requests to support referencing in more / all places and removed $ref labels Jan 27, 2024
@handrews
Copy link
Member

Consolidating under #3853 and closing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
re-use: ref-everywhere Requests to support referencing in more / all places
Projects
None yet
Development

No branches or pull requests

9 participants