Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to omit null field from Swagger/OpenAPI in ResponseEntity?

I'm trying to omit null values in my ResponseEntity.

My controller looks something like this:

@RestController
public class FooController {

    //fields
    //constructor

    @PostMapping
    public ResponseEntity<CreateFooResponseV10> createFoo(@Valid @RequestBody CreateFooRequestV10 foo, HttpServletRequest request) {
        //some minor logic
        return new ResponseEntity<>(aFooResponseV10Builder()
                .withFirstName(foo.getFirstName())
                .withLastName(foo.getLastName())
                .withTestField(NULLABLE_OBJECT)
                .build(), ...);
    //I generated the builders from the output classes openapi-generator provided
    }
    // more stuff...
}

When NULLABLE_OBJECT is equal to null I expect the field to be omitted from the response like this:

{
  "firstName": "John",
  "lastName": "Doe"
}

But I either get these responses, depending on what I've tried so far:

{
  "firstName": "John",
  "lastName": "Doe",
  "testField": null
}

or

{
   "firstName": "John",
   "lastName": "Doe",
   "testField": {"present":false}
}

I generate my request/response objects (CreateFooResponseV10 and CreateFooRequestV10) with the use of openapi-generator

Here is my redacted api.json file:

{
  "openapi": "3.0.1",
  "info": { ... },
  "servers": [ ... ],
  "paths": {
    "/foo": {
      "post": {
        ...
        "requestBody": {
          "description": "Foo to be created",
          "content": {
            "application/foo+json;version=1.0": {
              "schema": {
                "$ref": "#/components/schemas/CreateFooRequest_V1_0"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Foo is successfully created",
            "headers": { ... },
            "content": {
              "application/foo+json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateFooResponse_V1_0"
                }
              }
            }
          },
          ...
        }
      }
    }
  },
  "components": {
    "schemas": {
      "CreateFooRequest_V1_0": {
        "required": [
          "firstName",
          "lastName"
        ],
        "type": "object",
        "properties": {
          "firstName": { ... },
          "lastName": { ... },
          "testField": {
            "description": "...",
            "type": "string",
            "nullable": true
          }
        }
      },
      "CreateFooResponse_V1_0": {
        "required": [
          "firstName",
          "lastName"
        ],
        "type": "object",
        "properties": {
          "firstName": { ... },
          "lastName": { ... },
          "testField": {
            "description": "...",
            "type": "string",
            "nullable": true
          }
        }
      }
    }
  }
}

As you can see in both the request and response testField is not required and can be nullable. So when testField is null it should be hidden from the response, but when it contains some date it should be shown of course.

I've tried overriding jackson's ObjectMapper bean as explained in this answer. Didn't work.
I've tried adding spring.jackson.default-property-inclusion=non_null to the application.properties. Didn't work.

What I think should work is adding @JsonIgnore above testField of the generated classes, but I don't know if this is something needed to be done manually (for each schema component, can be a lot of manual work for something that is generated) or if this can be configured in the plugin somewhere.

Thanks in advance.


extra info
OpenAPI 3.0.1
Maven 3.6.3
Java 11.0.2
jackson-databind-nullable 0.2.1
openapi-generator-maven-plugin 4.2.2

like image 579
Edward Avatar asked Feb 18 '20 00:02

Edward


People also ask

How do you ignore null fields in JSON response?

You can ignore null fields at the class level by using @JsonInclude(Include. NON_NULL) to only include non-null fields, thus excluding any attribute whose value is null. You can also use the same annotation at the field level to instruct Jackson to ignore that field while converting Java object to json if it's null.

How do I ignore null values in post request body in spring boot?

Just use this @JsonSerialize(include = Inclusion. NON_NULL) instead of @JsonInclude(Include. NON_NULL) and it works..!!

How do I ignore null values in Jackson?

Jackson default include null fields 1.2 By default, Jackson will include the null fields. To ignore the null fields, put @JsonInclude on class level or field level.

How do I check if a JSON key is null?

To check null in JavaScript, use triple equals operator(===) or Object is() method. If you want to use Object.is() method then you two arguments. 1) Pass your variable value with a null value. 2) The null value itself.


2 Answers

You can set the following in application.properties

spring.jackson.default-property-inclusion = NON_NULL

See Customize the Jackson ObjectMapper

Note: To make use of this, you need to @Autowire the ObjectMapper, and not manually create it

like image 155
Justice Avatar answered Oct 05 '22 10:10

Justice


Try registering the following bean in your spring context. It should override default bean

@Bean
public HttpMessageConverters httpMessageConverters() {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setSerializationInclusion(Include.NON_NULL)
    return new HttpMessageConverters(
            new MappingJackson2HttpMessageConverter(mapper));
}
like image 32
Maxim Popov Avatar answered Oct 05 '22 10:10

Maxim Popov