3

I attempted to introduce nullable properties in an API which has been designed using openapi 3 specifications. The idea is to always return the properties to the client, whether their values are null or not.

YAML file (I tried first without default, with same results):

       property:
          type: integer
          nullable: true
          default: null

Generated Java code:

  @JsonProperty("property")
  private JsonNullable<Integer> property = JsonNullable.undefined();

Response from API:

  "property": {
    "present": true
  }

So the result is always "present: true" whether or not the property is null or not. Without nullability it works out just fine, except for the null values being removed from the response which is undesireable.

Any ideas?

P.S. The property isn't actually named as "property"

Edit: configuration:

<generateAliasAsModel>true</generateAliasAsModel>
<inputSpec>./api/interface1.yaml</inputSpec>
<generatorName>spring</generatorName>
<enablePostProcessFile>true</enablePostProcessFile>
<configOptions>
    <sourceFolder>src/main/java</sourceFolder>
    <library>spring-boot</library>
    <java8>true</java8>
    <interfaceOnly>true</interfaceOnly>
    <useOptional>true</useOptional>
</configOptions>
Magelan
  • 189
  • 1
  • 13
anotherNoob
  • 31
  • 1
  • 1
  • 3
  • Did you generate all your backend with openapi or you did just try to add this functionnality to an existing project? – Imaguest Feb 27 '20 at 09:15
  • This is an existing project, in which the rest api is generated by defining the interface(s) in an YAML file, then generating Java classes from it using the maven plugin. I added the nullable attribute to the YAML file, then ran the plugin and moved the generated classes to their appropriate places. – anotherNoob Feb 27 '20 at 10:06
  • Ok, but did you replaced only models/interfaces? I know there's some configuration comming with this feature, like a bean providing a `JsonNullableModule` – Imaguest Feb 27 '20 at 10:48
  • I did notice a similar problem in which the solution was to register JsonNullableModule (https://stackoverflow.com/questions/58800701/jsonnullable-is-not-serializing-its-value-with-jackson), but I'm unsure how to do it in this context. There isn't that much code coming with the code generation, apart from the model and interface packages. – anotherNoob Feb 27 '20 at 10:57
  • I suggest you to download the openapi-generator-cli (last release) and generate a spring project with a simple API spec with some nullable models. From it you will be able to see how to configure your existing project to be able to use JsonNullable properly – Imaguest Feb 27 '20 at 11:30
  • As I inspected the configuration options closely, I noticed there was this: – anotherNoob Feb 27 '20 at 11:51
  • true, setting it to false generated the rest of the code and I was able to figure out where the definition belonged – anotherNoob Feb 27 '20 at 11:51
  • Nice! You can post what you've done to resolve your issue and accept it as solution. It will be useful for other developers having the same troubles – Imaguest Feb 27 '20 at 12:15
  • 3
    hi i am having the same issue, what was the solution? – denfri.dev Sep 04 '20 at 08:43

2 Answers2

0

A property can be mentioned as nullable to pass null value in openApi. OpenApi generator wraps the datatype with JsonNullable as shown below.

private JsonNullable<String> firstField = JsonNullable.undefined();

The response you mentioned in your question says that the property is present but not the real value, this happens when the object is not serialized correctly. Just by registering JsonNullableModule should instruct how to serialize the parser such as jackson.

@Bean
public Module jsonNullableModule() {
   return new JsonNullableModule();
}

At least in the version org.openapitools:jackson-databind-nullable:0.2.1 I do not see such issues, meant no need to register the above been explicitly as it is take care by the library itself.

Maniganda Prakash
  • 4,702
  • 8
  • 34
  • 42
0

Thanks to the help of @maniganda-prakash I was able to resolve my issue by registering the module in a custom ObjectMapper that is used by the RestTemplate.

Something like this:

var objectMapper = new ObjectMapper().registerModule(new JsonNullableModule());
var httpMessageConverter = new MappingJackson2HttpMessageConverter(objectMapper);
var restTemplate = RestTemplateBuilder.restTemplate().build();
restTemplate.getMessageConverters().add(0, httpMessageConverter);   
stergipe
  • 125
  • 1
  • 1
  • 11