1

We are using SpringDoc OpenAPI with SpingBoot 2.3 and WebFlux and have Swagger UI on top of it (more precisely springdoc-openapi-webflux-ui 1.4.8).

Lately, we noticed that there is no way to differentiate a nullable / optional number (Double) from a primitive (double).

For example, the following class

@With
@Value
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public class CurrencyBalanceDto {
    double balance;
    Double hardCapping;
}

Results in the following OpenAPI Schema

"CurrencyBalanceDto": {
    "type": "object",
    "properties": {
        "balance": {
            "type": "number",
            "format": "double"
        },
        "hardCapping": {
            "type": "number",
            "format": "double"
        }
    }
}

Based on https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.2.md#schemaNullable, I would expect the hardCapping property to have "nullable": true

J_D
  • 3,526
  • 20
  • 31

2 Answers2

2

The quote from the documentation from the provided link:

nullable boolean Allows sending a null value for the defined schema. Default value is false.

So by default, all fields are not nullable. You need explicitly set a field as nullable either by using the annotations like @Null, @Nullable or with @Schema(nullable = true)

VadymVL
  • 5,366
  • 3
  • 26
  • 41
  • 1
    While, I agree that the OpenAPI spec states that by default value if not nullable, SpringDoc-OpenAPI is an implementation of that spec specifically for Spring. In Spring, everything is nullable unless the @NotNull from java validation. Hence, I find it odd if I need to add an annotation to specify that this field is nullable just for Swagger. – J_D May 17 '21 at 13:04
  • SpringDoc as implementation tries to strictly follow the specification. You could also try to ask this question here https://github.com/springdoc/springdoc-openapi/issues but I'm pretty sure that the answer will be the same. – VadymVL May 17 '21 at 15:02
0

The springdoc-openapi library does not mark values as nullable by default; it will only do so if something specific tells it to do so (e.g. @Schema(nullable = true)). This isn't ideal in my personal opinion, as it introduces a discrepancy between what the OpenAPI description claims is allowable and what actually is allowable.

That being said, even if it did, arguably it should automatically mark balance as nullable in this case. If the CurrencyBalanceDto type were only used as a response object, then yes, it would be guaranteed to never be null. However, Jackson by default allows allows deserialization of primitive values from null:, in this case the default for the given primitive type will be used instead of null (0 for int, 0.0 for double, false for boolean, etc.).

Because Jackson allows nulls for primitive values, it is in fact therefore valid by default for a null value to be passed as a primitive field of a request object . Without additional context, it would be impossible for springdoc-openapi to determine that such a field should be nullable.

Example

In your specific case, a null balance could be successfully passed to e.g. a POST endpoint that took a CurrencyBalanceDto:

POST /currency/balance HTTP/1.1
Host: example.com
Content-Type: application/json
Content-Length: 2

{}

This object would be received by the Spring controller as a CurrencyBalanceDto with balance of 0.0 and hardCapping of null.

M. Justin
  • 14,487
  • 7
  • 91
  • 130