How to specify a property can be null or a reference with swagger

28,340

Solution 1

Not easy to do that. Even almost impossible. Your options :

Wait

There is a very long discussion about this point, maybe one day it will be done...

Use vendors extensions

You can use vendors extensions like x-oneOf and x-anyOf. I have already taken this hard way: You must to upgrade all used 'swagger tools' to take into account these vendors extensions.

In my case, we needed 'only' to :

  • Develops our own Jax-RS parser with customized annotations in order to extract swagger API file from sources
  • Extends swagger-codegen to take into account these extensions to generate java code for our clients
  • Develops our own swagger-ui: to facilitate this work, we added a preprocessing step to convert our swagger schema with our extensions to a valid json schema. It's easier to find a module to represent json schemas than swagger schemas in javascript. By cons we gave up the idea to test the API with the 'try it' button.

It was a year ago, maybe now ...

Refactor your APIs

Many projects don't need anyOf and oneOf, why not us ?

Solution 2

OpenAPI 3.1

Define the property as anyOf of the $ref and type: 'null'.

YAML version:

foo:
  anyOf:
    - type: 'null'   # Note the quotes around 'null'
    - $ref: '#/components/schemas/Foo'

JSON version:

"foo": {
    "anyOf": [
        { "type": "null" },
        { "$ref": "#/components/schemas/Foo" }
    ]
}

Why use anyOf and not oneOf? oneOf will fail validation if the referenced schema itself allows nulls, whereas anyOf will work.

OpenAPI 3.0

YAML version:

foo:
  nullable: true
  allOf:
  - $ref: '#/components/schemas/Foo'

JSON version:

"foo": {
    "nullable": true,
    "allOf": [
        { "$ref": "#/components/schemas/Foo" }
    ]
}

In OAS 3.0, wrapping $ref into allOf is needed to combine the $ref with other keywords - because $ref overwrites any sibling keywords. This is further discussed in the OpenAPI Specification repository: Reference objects don't combine well with “nullable”

Solution 3

For OpenAPI 3.0 for some reason using nullable: true followed by allOf didn't work for the OpenAPI interpreter I'm using. As a workaround I ended up defining a must-be-null ref called null_type that I can use in an anyOf construct.

Like so:

allOf:
  - anyOf:
      - $ref: "#/components/schemas/null_type"
      - $ref: "#/components/schemas/your_ref"
  - description: "optionally add other properties here..."

where:

schemas:
  null_type:
    title: "OpenAPI 3.0 null-type ref"
    description: "for adding nullability to a ref"
    enum: [null]

  your_ref:
    ...
Share:
28,340

Related videos on Youtube

djpinne
Author by

djpinne

Updated on January 27, 2022

Comments

  • djpinne
    djpinne over 2 years

    How to specify a property as null or a reference? discusses how to specify a property as null or a reference using jsonschema.

    I'm looking to do the same thing with swagger.

    To recap the answer to the above, with jsonschema, one could do this:

    {
       "definitions": {
          "Foo": {
             # some complex object
          }
       },
    
       "type": "object",
       "properties": {
          "foo": {
             "oneOf": [
                {"$ref": "#/definitions/Foo"},
                {"type": "null"}
             ]
          }
       }
    }
    

    The key point to the answer was the use of oneOf.

    The key points to my question:

    1. I have a complex object which I want to keep DRY so I put it in a definitions section for reuse throughout my swagger spec: values of other properties; response objects, etc.

    2. In various places in my spec a property may be a reference to such an object OR be null.

    How do I specify this with Swagger which doesn't support oneOf or anyOf?

    Note: some swagger implementations use x-nullable (or some-such) to specify a property value can be null, however, $ref replaces the object with what it references, so it would appear any use of x-nullable is ignored.

  • djpinne
    djpinne over 7 years
    "Wait" - yes, apparently v3 is going to support oneOf, anyOf, but then we have to wait for the tooling and libraries that consume it.
  • djpinne
    djpinne over 7 years
    "Extensions" - I'm consuming my swagger in python (w/ bravado-core) which does not have the extensions you mention...bummer.
  • djpinne
    djpinne over 7 years
    "Refactor" - that would require dumbing down my api to fit the spec...I need the spec to fit my api! The only other thing I could think to do for the case of returning $ref-or-null now is not return the property which in the case of clients (javascript in my case) would treat "undefined" as "null". But I loathe that idea.
  • Adam Diament
    Adam Diament almost 4 years
    I'm using swashbuckle 5x on .net core and I want to add "nullable": true to "payload": { "$ref": "#/components/schemas/MyClass" }, so it's "payload": { "nullable": true, "$ref": "#/components/schemas/MyClass" }, Does anyone know of a swashbuckle option to do this?
  • Helen
    Helen almost 4 years
    @AdamDiament please ask a new question
  • Adam Diament
    Adam Diament almost 4 years
    Thanks Helen, I've done that here