express-openapi-validator
express-openapi-validator copied to clipboard
Nullable object property fails to validate `null`
Describe the bug
I'm working with an API that requires differentiating between properties that are T | undefined
or T | null
.
In OpenAPI 3.0, T | null
properties seem to be modelled like:
schemas:
TestObject:
type: object
properties:
otherObjectMaybeNullA:
$ref: "#/components/schemas/OtherObject"
nullable: true
otherObjectMaybeNullB:
anyOf:
- $ref: "#/components/schemas/OtherObject"
nullable: true
required:
- otherObjectMaybeNullA
- otherObjectMaybeNullB
OtherObject:
type: object
In both cases the validator does not accept null
as a valid value. Errors are 'should be object'
and 'should match some schema in anyOf'
.
To Reproduce
Validate above against { otherObjectMaybeNullA: null, otherObjectMaybeNullB: null }
.
Actual behavior
Validation fails.
Expected behavior
Validation should pass.
Examples and context
See above.
@bluenote10
Using the first form e.g. nullableObjectMaybeNullA
, nullable
would be ignored given its a sibling to the $ref
, hence that won't work.
The second form is, well, complicated, see https://github.com/OAI/OpenAPI-Specification/issues/1368
That being said, I did some playing around. The following will pass validation:
Note: moving nullable: true
to OtherObject
TestObject:
type: object
properties:
nullableObject:
$ref: '#/components/schemas/OtherObject'
required:
- nullableObject
OtherObject:
type: object
nullable: true
There is some good news. It looks like when OAS v3.1.0 is released, nulllable
will be deprecated in favor of a null
type. This should make things much more straightforward. 3.1.0 (as of now) has not been released/finalized.
In the meantime, the above example works. Hopefully, it fits your use case
Thanks for looking into this! Yes, that seems to be a bit of a mess in OpenAPI 3.0. My interpretation of Clarify Semantics of nullable in OpenAPI 3.0 was that at least the second form is valid. Other indicators:
- The online swagger validator shows the second form as valid, and actually outputs a warning for the first case to change it into the second form.
- When I raised the same issue for swagger-typescript-api support for both forms was added.
Looks like I'm a bit stuck in terms of work-arounds because:
- I can't migrate to OAS 3.1.0 yet, because other libraries depending on the API definitions don't support it yet.
- Regarding moving
nullable: true
toOtherObject
. This other object is intended to appear in non-nullable form in other places. I naively thought I can wrap it intoOtherObjectNullable
, but that again results in having to combine$ref
withnullable: true
. This maybe leaves duplicating all fields inOtherObject
andOtherObjectNullable
as an option, which calls for trouble when changing the fields and forgetting to sync them.
@cdimascio
v4.5.0
Nullable objects can't be validated if properties are defined in the openapi.json.
This one works (nestedObject can be null or object)
ObjectOne:
type: object
additionalProperties: false
required:
- id
- username
properties:
id:
type: string
format: uuid
readOnly: true
username:
type: string
nestedObject:
nullable: true
type: object
This one can't be null (error: .response.ObjectOne.nestedObject should be object)
ObjectOne:
type: object
additionalProperties: false
required:
- id
- username
properties:
id:
type: string
format: uuid
readOnly: true
username:
type: string
nestedObject:
nullable: true
type: object
required:
- name
- id
properties:
id:
type: string
format: uuid
name:
type: string
@dotMortis Both of your examples produce the same error for me. I'm using v4.12.9 and I cannot get a nested property to be nullable no matter what I do. Though in my case it's nested twice: ObjectOne.NestedObject.NullableProperty
"data": {
"oneOf": [
{
"$ref": "#/definitions/348",
"x-apifox-overrides": {}
},
{
"type": "null"
}
],
"x-apifox-overrides": {},
"$ref": "#/components/schemas/ChatClientSettings"
}
},
can't handle this oneof ?
Nullable objects can't be validated if properties are defined in the openapi.json.
Why can't it validate nullable objects with properties defined??