-
Notifications
You must be signed in to change notification settings - Fork 9.1k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
DRY Specifications via $ref #1462
Comments
@BenjamenMeyer I'm one of the editors of the JSON Schema spec. There are a couple of things going on here, some due to JSON and YAML, and others specific to OAS. As phrased, none of this is actually about JSON Schema. For all practical purposes, JSON does not allow allow duplicate keys in objects. They do not technically violate the RFC, but the RFC notes that the behavior is undefined and therefore not interoperable. Furthermore, YAML absolutely requires unique keys. So your number 3, putting multiple The correct way to have multiple allOf:
- $ref: '#/components/headers/x-my-header-1'
- $ref: '#/components/headers/x-my-header-2'
- $ref: '#/components/headers/x-my-header-3' which reduces your 3 to a combination of 1 and 2. Those are limitations of OAS. JSON Schema allows |
Just to clarify, OASv3 also allows a
and also allows
What is not allowed is using a If you wish to experiment with allowing PS: I appreciate the above is just an example, but it is not recommended to |
@MikeRalphson OK the reference object rules in OAS match how JSON Schema works. In older drafts it was outside of the spec and therefore could be used anywhere, but we changed that in draft-05. We have strong reasons for not allowing $refs to things other than schemas but it's also a long story so I'll leave it at that :-) |
Sorry for delay - trying to figure out what I wanted to say more properly... @MikeRalphson per your "PS" that's kind of my point here is that $ref should be valid there; $ref should be more generic in usage so that anything can be pointed to; it should still be valid for the kind of contents that go in that section, but it should be valid. IOW one can write:
Then:
or event
kind of thing ought to be valid so Again - I'm new OAS so trying to understand how all this applies to maximize DRY/re-use in writing a big spec. From what I've been told (outside of here), using $ref is a lot more restricted; but if I'm understanding you all correctly, reality is somewhere between that extremely restrictive view and what I'm asking here. @handrews If it's not possible, I'd be interested in reading up. Do you have a link to an PR/Issue/etc I could follow for the background? |
@BenjamenMeyer I'm not sure I follow your example as the only recognizable JSON Schema keyword is Sorry I did not notice that you'd updated this, I try to keep on top of at-mentions but this one slipped through. |
@handrews no problem: I'm not on github.com as much myself nowadays either so I may take a bit longer to respond too. To answer your question, my example is very generic, kind of on purpose - so everything falls into being an To try to bring some more clarity...
But to take a stab at it against what I was doing it'd be something like:
Essentially, once past the basic path, almost anything could use a And yeah, I know - I'm not following the general structure of the field naming at the top level; but this should be able to be structured in a way that makes sense to document writers and enables them to easily expand the document out and re-use material. |
@BenjamenMeyer sounds like you are looking to add more Since With my "interested party but not all that proficient in OpenAPI" hat on, I generally like allowing @BenjamenMeyer you asked about the history of only allowing The problem with this is that if you can use If you go further and say that you can do something like That is an incredibly complex topic spread across numerous issues across at least two repositories with well over 500 comments in total. If you really want to know I'll point you to them, but I recommend against it. The TL;DR is "it doesn't solve as many problems as you think, and it introduces new and extremely difficult problems as well". In place of schema merging/splicing, we are pursuing json-schema-org/json-schema-spec#556. It may not be obvious how those relate, but again, the backstory is extremely involved. |
@handrews thanks for the insight. I can certainly understand the issue with the |
@handrews @MikeRalphson but what about combining objects other than schemas, since they are json (yaml?) instances can't we just do something like
Which would just do a deep copy of both json instances... Jackson implemented this here FasterXML/jackson-databind#1399 |
|
Just to point out that YAML has anchors and you can work around this issue today. Example
Now I know it's a different story for JSON, but most examples in this thread were in YAML. Hopefully this helps. |
@fenollp The reason |
So I realize there is some discussions regarding some "similar" things, but I'm not quite sure they're similar enough - if so, please say so and I'll contribute to the other discussions accordingly and close this one out. Other similar but not quite as extensive discussions I have found:
Basically, one should be able to write their OpenAPI specification in as DRY a manner as possible. Presently this is not possible because:
$ref
is not valid at all the right placesallOf
is not valid at the right places (which could make up for point 1)$ref
can't be specified numerous times next to itself appropriatelyLet's give this some better clarity via an example. Discussing API Header Fields provides a good example such as the following which similar to #417 but I'm going more general where that seems to be focused on path objects:
The above is missing a lot of stuff, but only in order to show the re-use and avoid having to put a complete spec here. I know some of the above can be fixed by moving up a layer in the referencing, e.g create a component for the header set and reference that instead; however that can then dictate a bad spec by forcing all headers to be pushed to header sets which then can also be an issue for 1-off header combinations.
Goal here is to enable spec writers to manage their specifications by creating re-usable modules that can be continuously re-used. To achieve this,
$ref
would need to be valid in essentially ever object to replace anything in the object. F.e if you have adescription
field you want to re-use, define it once and use it 10 times.Two parallel
$ref
values should be valid and able to point to separate objects, neither being discarded, orallOf
could be used to combine the contents of both$ref
references to create the same effect (good solution for one-offs).When building larger APIs using tooling like OpenAPI being able to be a DRY as possible is key to keeping bugs from creeping into the specs as it reduces the ability for any one instance to be mis-typed. For instance, if you had to type
x-my-header-3
for every single Request object andx-my-header-2
for every single Response object - one typo ofmy-header-3
orxmy-header-3
could easily create something hard to detect where using the $ref objects would make it fail validation and be easily caught in gate checks (PR builders, etc).To re-iterate - please let me know if I need to file this with JSON Reference/Schema too. I did not find anything suitably talking about these aspects while reading through any of the repos I came across, but have in general there does seem to be some of sentiment that this is an issue.
The text was updated successfully, but these errors were encountered: