-
Notifications
You must be signed in to change notification settings - Fork 270
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
Optional object references are non-compliant with OpenAPI specification 3.0.3 #925
Comments
Hi @TimoGuenther,
I don't fully understand. It is This construction is due to nature of references. They replace themselves (and their context) with the content of that child:
type: object # the substituted Child ref
properties: ... # the substituted Child ref
nullable: true Which looks as it is intended I suppose.
I don't understand how this is supposed to work. From my perspective this is actually a NOP in that example.
That might be an issue with the generator target. openapi-generator is by no means complete or flawless and different targets behave differently. It is not the best indicator for schema validity. Have you checked against I see your points, however this will introduce another hardcoded prefix, which may produce collisions. Also it will increase parsing complexity and it will require another postprocessing step as you cannot know all the usages beforehand and so cannot decide on whether to use |
This is a comment of one of the main contributors, which seems to support my interpretation: OAI/OpenAPI-Specification#1368 (comment)
Also I do interpret the official clarification in my favor. (subtype/subschema refers to what is included in
Given all this, I think your 3rd yaml snippet is even "less correct" and violates the clarification. I think this aspect of OpenAPI 3.0.x is a hot mess and the fact that there were thousands of words written on this topic show that is not that clear cut. There is still very little clarity, and no bullet-proof definition to depend on. |
Thanks for the elaborate reply, @tfranzel. I hope my lengthy response does it justice.
I agree. Certainly, we both would like to spend our time more meaningfully than to debate something that seems as trivial as nullable references. :) But let us proceed for the sake of correctness.
We both agree on step 1: child:
allOf:
- type: object
properties: ...
nullable: true However, the question is whether step 2 really simply inlines the keywords from
But JSON Schema does not concern itself with inlining vs. including for
To JSON Schema, it's all just additional constraints where each keyword stands alone. Since we are interested in the case of two keywords (
JSON Schema defines subschema as you do. I could not find a definition for subtype, but in accordance with typical type inheritance like in OOP, I would argue that the directionality of type is the opposite: Subschema actually correlates more closely to supertype (not subtype), because a subtype extends a supertype by adding constraints to an existing subschema. With that interpretation, those two official clarification statements you quoted support my interpretation of That interpretation also explains the inheritance of In any case, the following statement from the official clarification works regardless of direction of type:
To me, this is saying pretty explicitly that the
That comment predates OAS 3.0.3 by several years. There has since been a lot of back and forth on that topic. Even if singular
Good point. Indeed, most targets align with your definition and treat the property in question as nullable; of the ones I tested, only
Of course, it is also common to accept non-compliant features like the future
I understand; feasibility is, of course, another valuable consideration beside correctness. Perhaps an easy and only slightly redundant solution is to ensure bulletproof activation of child:
type: object
allOf:
- type: object
properties: ...
nullable: true This requires |
DRF Spectacular translates optional object references (e.g.,
child: Child | None
in Python) to OpenAPI like this:However, while looking intuitive, this
nullable
statement is actually a no-op according to the OpenAPI specification version 3.0.3 to which DRF Spectacular adheres --nullable
only does anything when it istrue
and adjacent totype
:Further reading on this:
nullable
Indeed, in compliance with the specification, the OpenAPI generator for Python disallows a value of
None
forchild
with the above schema.To fix this, in OpenAPI 3.1.0, we could say:
Unfortunately,
type: 'null'
is not yet supported in OpenAPI 3.0.3. Instead, we have to differentiate the optional type:There are a few options to lessen the unwieldiness of this solution:
nullable
on the sole (non-prefixed) generated type as needed.The text was updated successfully, but these errors were encountered: