Deprecate discriminator?
See original GitHub issueI just created an example to illustrate what I think is idiomatic use of discrimator
, so I could help answer #2141. I find it helpful to use JSON Schema Lint so I can validate in real-time. To make sure the discriminating logic worked correctly in a standard JSON Schema validator (not aware of OAS discriminator
), I used standard JSON Schema keywords to duplicate that logic.
This begs the question: now that 3.0 supports a large-enough subset of JSON Schema to describe discriminated subtypes, and 3.1 is planned to support full JSON Schema, do we still need discriminator
?
@handrews mentions the same idea here in #2031, so I think the idea deserves its own issue for future version planning.
I can see that discriminator
might have some value for code generators. It might be easier for a code generator to be told explicitly to discriminate based on a given property, rather than relying on a JSON Schema validator to identify the matched subtype, or recognizing a pattern involving oneOf
, enum
(or const
), etc.
But discriminator
, as it’s defined, is kind of problematic. @handrews pointed out that it ignores some available JSON Schema semantics. And I’ve observed, generally, that the documentation is difficult (for me) to follow, and seems to leave some questions unanswered. Without trying to create a comprehensive list here:
- I have doubts about the combination of
mapping
and default name matching shown in the last example of this section. - It seems that
mapping
is supposed to be supplemental to name matching, rather than replacing it. In that case, is there a way for the discriminator to ensure that the discriminator property value is one of a known list of subtypes? Do we always need a separateoneOf
to validate this? - Does name matching (without
mapping
) assume it’s going to find the named subtype schema in#/components/schemas
, or is there some other expectation?
Maybe this is more weight than we need to carry, and we’d be better off leaving this problem to JSON Schema and some new vocabulary for code generation, O-O type system mapping, or something like that.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:10
- Comments:102 (45 by maintainers)
Top GitHub Comments
In the hope that it will inform this discussion, I’ll describe how we (IBM) are using discriminators in our APIs and code generation tools.
Here’s an example use of discriminator in the API for the IBM Discovery service:
QueryAggregation
is “class” of schemas that may be returned from a query that requests aggregation of results in various forms. The various aggregation types vary quite significantly, but notice that some types, e.g. “max”, “min”, “average”, share a common schema. In this particular case, the “child” schemas are composed usingallOf
withQueryAggregation
as one element and then the specific properties of the child in a second element. E.g.Next I’ll describe how this is used in our tooling. The first thing to say about our SDK generation tooling is that it does not do any validation based on JSON schema. Some may consider this heresy, but we use the schemas in the API def purely for modeling.
In Java and similar type-strict languages, the QueryAggregation schema is rendered as a public class (it is not abstract, but if the composition were “flipped” to use
oneOf
it would be). The “child” schemas are rendered as subclasses ofQueryAggregation
, e.g. Calculation.The
discriminator
in theQueryAggregation
schema is rendered into theQueryAggregation
class as static metadata:This metadata is used by our deserialization logic to trigger and guide the use of a custom TypeAdapter that is created in
DiscriminatorBasedTypeAdapterFactory
. The custom TypeAdapter uses the value of the discriminator to choose a concrete class, based on the discriminatorMapping metadata in the class, to be produced by the deserialization logic.If there were no discriminator, the generated code would look very different. We would instead create a
QueryAggregation
class containing the union of all the properties of the child schemas, and the returned class would be an instance of this “generic” QueryAggregation class.Sorry for the long post. I hope this has been clear and informative.
Clarity of intent. Standardized, unambiguous way to denote tagged unions, rather than relying on a loosely defined convention. “Convenience” translates into availability of code generators, validators and other tools: more of them, better consistency, and higher quality. All good things for the OpenAPI ecosystem and user community. These are the reasons described in recent posts here.
I’m not arguing that it’s ideal to keep
discriminator
in its current form, in OpenAPI, forever. But I would like to see it replaced by a JSON Schema vocabulary that has the same level (at least) of clarity, consistency, and simplicity.