OpenAPI-Specification
OpenAPI-Specification copied to clipboard
Feature Request: $ref for Operation Object
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).
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.
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.
It's not currently supported by the spec, and @cebe's example is unfortunately invalid.
@webron thanks. Are you aware of any technical reasoning against supporting this? And if not, what would it take to add to the spec?
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.
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?
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).
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...
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...
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.
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.
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?
Folks interested in this issue may be interested in the more general discussion of referencing that is now just getting started.
We are interested in the same issue, any news?
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. :(
@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.
@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.