Enhancement: change `ModelResolver` to use `"nullable": true` for "non"-required properties based on default property inclusion of object mapper
As part of my SpringBoot application that uses the springdoc-openapi library (using swagger-core under the hood) to generate OpenAPI specs, I would like automatically generate .nullable(true) for "non"-required properties.
This because by (Jackson) ObjectMapper is configured with:
.setSerializationInclusion(JsonInclude.Include.ALWAYS)
This causes Jackson includes null property values when it serializes JSON as opposed to omitted them.
But this means that every "non"-required property in de OpenAPI spec should also have "nullable": true.
However, the ModelResolver currently only adds a "nullable": true (based on what I digested from reading its source-code) in case nullable = true was specified to an @Schema(..) annotation.
But since I already use @NotNull annotations, I do not also want to also use @Schema(..) annotations.
What if we would change the ModelResolver to automatically adds nullable = true for "non"-required properties based on the "default property inclusion" in object mapper?
So that in case of JsonInclude.Include.ALWAYS the ModelResolver automatically adds nullable = true for "non"-required properties.
The "default property inclusion" could easily be determined using the (overloaded) getDefaultPropertyInclusion method of the SerializationConfig config (that can be retrieved calling .getSerializationConfig() on the object mapper.
References:
- https://github.com/springdoc/springdoc-openapi/issues/1275
Going a step further, under its default configuration Jackson will deserialize nulls from a request JSON the same way it would a missing property. So for any request arguments, all optional properties should be nullable. Or at least, it would be nice to be able to opt into it.
Technically shouldn't a property be marked as nullable (null is a valid type) specifically if:
- Property is NOT required AND the type is a non-primitive type (and Jackson
JsonInclude.Include.ALWAYSis on)
I think there should be distinction between primitive vs non-primitive types here.