Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarification on nullable properties, OpenAPI 3.1 #3148

Closed
stephenfin opened this issue Jan 25, 2023 · 7 comments
Closed

Clarification on nullable properties, OpenAPI 3.1 #3148

stephenfin opened this issue Jan 25, 2023 · 7 comments

Comments

@stephenfin
Copy link

OpenAPI 3.1 introduces support for jsonschema's 'null' type, however, the OpenAPI 3.1 spec makes no mention of this leading to confusion on how to specify null objects. I've seen two common ways to represent nullable properties in the wild.

Option A

openapi: '3.1.0'
components:
  schemas:
    Foo:
      type: 'object'
      properties:
        bar:
          type: ['string', 'null']
          format: 'uri'
          maxLength: 255

Option B

openapi: '3.1.0'
components:
  schemas:
    Foo:
      type: 'object'
      properties:
        bar:
          oneOf:
            - type: 'string'
              format: 'uri'
              maxLength: 255
            - type: 'null'

Option A is more succinct but arguably incorrect, since format and maxLength are not applicable for the null type. It is rather common though. For example, GitHub's OpenAPI 3.1 specs does this:

---
openapi: 3.1.0
# ...
paths:
  # ...
  "/authorizations":
    # ...
    post:
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                scopes:
                  description: A list of scopes that this authorization is in.
                  type:
                  - array
                  - 'null'
                  items:
                    type: string
                  examples:
                  - public_repo
                  - user
                # ...

Option B is longer but appears (to me) to be technically correct.

Could we clarify which of these is correct? I assume we'd need a future MINOR or PATCH version if we wanted to (correctly?) forbid option A?

@stephenfin
Copy link
Author

I'm aware this might be an issue with jsonschema itself too. If it makes sense for me to do so, I could close this issue and report a new one against jsonschema.

@stephenfin
Copy link
Author

Hmm, I actually think JSONSchema allows for option A. From the spec:

7.6.1. Assertions and Instance Primitive Types

Most assertions only constrain values within a certain primitive type. When the type of the instance is not of the type targeted by the keyword, the instance is considered to conform to the assertion.
For example, the "maxLength" keyword from the companion validation vocabulary [json-schema-validation]: will only restrict certain strings (that are too long) from being valid. If the instance is a number, boolean, null, array, or object, then it is valid against this assertion. This behavior allows keywords to be used more easily with instances that can be of multiple primitive types. The companion validation vocabulary also includes a "type" keyword which can independently restrict the instance to one or more primitive types. This allows for a concise expression of use cases such as a function that might return either a string of a certain length or a null value:

{
    "type": ["string", "null"],
    "maxLength": 255
}

If "maxLength" also restricted the instance type to be a string, then this would be substantially more cumbersome to express because the example as written would not actually allow null values. Each keyword is evaluated separately unless explicitly specified otherwise, so if "maxLength" restricted the instance to strings, then including "null" in "type" would not have any useful effect.

Assuming I've understood this correctly, both are valid options and it's a case of determining whether clarity trumps succinctness or not. I, for one, would love to see this detailed in the spec itself so I'll leave this open as a kind of docs RFE.

@hkosova
Copy link
Contributor

hkosova commented Jan 30, 2023

Both options are valid. Sometimes there are multiple ways to define the same thing with JSON Schema.

Option A is more succinct but arguably incorrect, since format and maxLength are not applicable for the null type.

Type-specific keywords (such as string-specific maxLength or number-specific maximum) don't apply when the instance being validated is of another data type. In case of Option A, the format and maxLength constraints only have effect when the value of bar is a string and are ignored when bar is null.

@handrews
Copy link
Member

@hkosova is correct.

Perhaps an example using "type": ["integer", "null"] or something similar can be added in the Schema Object section in 3.1.1?

We do not want to get into things like keyword applicability to types as that is a JSON Schema concern and OAS should not duplicate JSON Schema stuff.

@handrews
Copy link
Member

It's been nearly a year since multiple folks answered with "both are valid" and no further questions, so I'm closing this as resolved.

@XedinUnknown
Copy link

According to the spec, neither are valid.

@hkosova
Copy link
Contributor

hkosova commented Jun 27, 2024

@XedinUnknown that doc is about OpenAPI 3.0, whereas this discussion is about 3.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants