cdimascio / express-openapi-validator

🦋 Auto-validates api requests, responses, and securities using ExpressJS and an OpenAPI 3.x specification
MIT License
914 stars 208 forks source link

Nullable object property fails to validate `null` #266

Open bluenote10 opened 4 years ago

bluenote10 commented 4 years ago

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.

cdimascio commented 4 years ago

@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

bluenote10 commented 4 years ago

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:

Looks like I'm a bit stuck in terms of work-arounds because:

dotMortis commented 3 years ago

@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
BlueSialia commented 2 years ago

@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

Akimyou commented 2 years ago
                "data": {
                  "oneOf": [
                    {
                      "$ref": "#/definitions/348",
                      "x-apifox-overrides": {}
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "x-apifox-overrides": {},
                  "$ref": "#/components/schemas/ChatClientSettings"
                }
              },

can't handle this oneof ?

tobq commented 2 years ago

Nullable objects can't be validated if properties are defined in the openapi.json.

Why can't it validate nullable objects with properties defined??