Use of oneOf with a discriminator, when the child schemas are identical? #3608
-
Hello, SituationFor an example I will use the Cat/Dog/Lizard/etc example, and for your information, I am using v3.0.1 of the spec (however this question seems relevant for at least all 3.x.y versions). I have currently tried to use Note that in my example I have:
This looks like so: components:
schemas:
PetType:
oneOf:
- $ref: '#/components/schemas/Cat'
- $ref: '#/components/schemas/Dog'
- $ref: '#/components/schemas/Lizard'
- $ref: '#/components/schemas/Snake'
discriminator:
propertyName: pet_type
mapping:
CAT: '#/components/schemas/Cat'
DOG: '#/components/schemas/Dog'
LIZARD: '#/components/schemas/Lizard'
SNAKE: '#/components/schemas/Snake'
Cat:
description: A representation of a cat
type: object
properties:
pet_type:
type: string
description: The type of the Pet.
huntingSkill:
type: string
description: The measured skill for hunting
enum:
- clueless
- lazy
- adventurous
- aggressive
required:
- pet_type
- huntingSkill
Dog:
description: A representation of a dog
type: object
properties:
pet_type:
type: string
description: The type of the Pet.
packSize:
type: integer
format: int32
description: the size of the pack the dog is from
default: 0
minimum: 0
required:
- pet_type
- packSize
Lizard:
description: A representation of a lizard
type: object
properties:
pet_type:
type: string
description: The type of the Pet.
lovesRocks:
type: boolean
required:
- pet_type
Snake:
description: A representation of a snake
type: object
properties:
pet_type:
type: string
description: The type of the Pet.
lovesRocks:
type: boolean
required:
- pet_type I had initially thought this was valid, but after some issues with code generation I wondered if it is not. Looking at the Specification on Discriminator Objects it says:
If I read this correctly, the "MUST" part says that the specification must be able to identify which schema a payload will map to using the field names and the presence of values alone, and the discriminator is an optional shortcut, but should be unnecessary. And so, this above setup may not be valid, because there is no unique fields between Concrete ObservationsI was using some tooling for generation of these examples, so while I understand that the tooling is external to the specification, I will just give some details of what I observed. Feel free to ignore. Using Swagger Editor showed no issues with the specification. And while using OpenAPI Generator the specification again showed no warnings, and I saw:
But, obviously these can be ignored as implementation specifics. QuestionIs it valid to have multiple schemas under a OneOf which fields are the same? And if not is there another recommended way to do this? My thoughts currentlyI was especially considering how OneOf can handle schema evolution. If this is a valid pattern according to OAS, that is good, and I can continue to use the generator with the understanding that it should be supported. If it is invalid, it feels like this will rule out the use of Thanks for any thoughts/advice. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
Hey @davidjlynn , oneOfs are incredibly hard to understand. It's more about the a validation rule for a json instance than it is about a polymorphic "type system". I wrote a blog to help folks sort this out https://medium.com/@smikulcik/oneof-explained-c0264c429735 But yeah. If you have two identical oneOf options. No JSON instance that validates against either of those options can validate against the oneOf object. |
Beta Was this translation helpful? Give feedback.
-
Please take a look at similar discussion on softwaremill/tapir#3909 Long story short - to me it seems
All done - it works perfectly. But we can do better I believe: All done - everything is precise, uses already existing concepts, parsers if they wish can build lookup tables for discriminator values, no need to store mapping table explicitly anywhere in the schema. |
Beta Was this translation helpful? Give feedback.
Hey @davidjlynn , oneOfs are incredibly hard to understand. It's more about the a validation rule for a json instance than it is about a polymorphic "type system".
I wrote a blog to help folks sort this out https://medium.com/@smikulcik/oneof-explained-c0264c429735
But yeah. If you have two identical oneOf options. No JSON instance that validates against either of those options can validate against the oneOf object.