Closed kristof-mattei closed 3 years ago
Hey @Kristof-Mattei. This is a brain scratcher. I've spent some time looking at this and am still trying to figure it out.
The problem of determining the type can become increasingly difficult when we run into allOf
with nested oneOf
or anyOf
.
Also, you mentioned that it may not be possible to have an allOf
with the type not object
. When I originally built the library that was my impression too, but as I've continued to grow the library I've found that is not the case. Here is an example:
components:
schemas:
AllNumbers:
allOf:
- $ref: '#/components/schemas/Number1'
- $ref: '#/components/schemas/Number2'
Number1:
type: number
minimum: 0
Number2:
type: number
maximum: 10
I've spent a lot of time trying to solve this and the conclusion I've come to is that this might need to wait for Enforcer version 2 to fix. For now the best solution is probably to create a schema that includes all 3 allOf schemas.
I created an ObjectX
schema below as an example.
components:
schemas:
ObjectX:
allOf:
- $ref: "#/components/schemas/Object2"
- $ref: "#/components/schemas/Object3"
- $ref: "#/components/schemas/Object4"
Object1:
allOf:
- $ref: "#/components/schemas/Object2"
- type: object
required:
- date
properties:
date:
type: string
format: date-time
Object2:
# type: object # THIS LINE
allOf:
- $ref: "#/components/schemas/Object3"
- $ref: "#/components/schemas/Object4"
Here I am again! This time with an issue where I do have a solution for, but I am trying to understand whether it should work without my solution.
Let's get started with our schema:
And our test code:
When we run this we get
However, in our schema, in
Object2
you'll notice that I've commented out thetype: object
. That was on purpose. I originally missed that, because when I create a schema calledFoo
withproperties
openapi-enforcer
deduces that it is oftype: object
.With
Object2
this is not the case. I explicitely need to specifytype: object
otherwise the deserializers ofObject1.allOf[1]
don't run, becauseObject1.allOf[0]
wasn't oftype: object
: https://github.com/byu-oit/openapi-enforcer/blob/e29d5b35bd8fd55f065d7476907234ad51cba21f/src/schema/deserialize.js#L50Now, I see 3 solutions, in order of what I think is more correct to less correct.:
allOf
, it checks for the presense oftype: object
as a sibling. If not present, it adds it, somewhere around here: https://github.com/byu-oit/openapi-enforcer/blob/e29d5b35bd8fd55f065d7476907234ad51cba21f/src/enforcers/Schema.js#L256type: object
to ourObject2
and be explicit.if
clause as follows:if (schema.allOf[0].type === 'object' || !!schema.allOf[0].allOf)
I've spent some time thinking if it's possible to create a schema with
allOf
and itstype
not to beobject
... and I cannot come up with anything.E.g.:
Like what would
Object1
really be?Edit: I've also created a repl.it with everything inline to easier validation: https://repl.it/@KristofMattei/ViciousCyberKeygens#index.js