Skip to content

Could @Schema(nullable = true) work when outputting OpenAPI 3.1.0? #4555

Closed

Description

@karlvr

Due to the removal of nullable: true from schema in 3.1.0, it appears that the nullable = true property on the @Schema annotation no longer works. That isn't obvious in the documentation for the annotation, and it's inconvenient to boot ;-)

I think it will be quite easy to continue to support the nullable attribute under 3.1.0, I suggest a little change to Schema.getTypes:

    @OpenAPI31
    public Set<String> getTypes() {
        if (types != null) {
            if (nullable != null && nullable.booleanValue()) {
                Set<String> ss = new LinkedHashSet<>(types);
                ss.add("null");
                return ss;
            } else {
                return types;
            }
        } else {
            return null;
        }
    }

We simply add "null" to the list of types if the schema is nullable... which ends up nicely in the schema output.

I'm happy to make a PR of this, or a better suggestion, or I'd love to know if this is more like the wrong approach!

Activity

  1. karlvr commented on Nov 24, 2023

    @karlvr
    Author

    Ugh, nullable properties that use a $ref aren't that simple... it seems they need to transform into:

    allOf:
      - $ref: '#/...'
      - { type: "null" }

    Heh, I'm not immediately a fan of OpenAPI 3.1 :-D

    Instead I've solved this with a filter. If you, the maintainers, think that support for Schema.nullable is nice for OpenAPI 3.1 support, I'd be happy to work on a PR, otherwise I'll leave this filter here for anyone else in this predicament to enjoy and please close this issue!

    import java.util.List;
    import java.util.Map;
    import java.util.Optional;
    
    import io.swagger.v3.core.filter.AbstractSpecFilter;
    import io.swagger.v3.core.util.AnnotationsUtils;
    import io.swagger.v3.oas.models.SpecVersion;
    import io.swagger.v3.oas.models.media.Schema;
    
    /**
     * A filter to add support for {@link Schema#getNullable()} under OpenAPI 3.1.0. As of swagger-core 2.2.19 that property
     * is ignored when serializing to OpenAPI 3.1.0. This filter modifies property schemas to translate nullable to
     * OpenAPI 3.1.0.
     * <p>
     * OpenAPI 3.1.0 doesn't directly support {@code nullable} anymore; instead we must add {@code null} to the array of types.
     */
    public class NullableToOpenAPI31Filter extends AbstractSpecFilter {
    
    	@Override
    	public Optional<Schema> filterSchemaProperty(Schema property, Schema schema, String propName,
    			Map<String, List<String>> params, Map<String, String> cookies, Map<String, List<String>> headers) {
    		if (property.getNullable() != null && property.getNullable().booleanValue()) {
    			if (property.get$ref() != null) {
    				Schema clone = AnnotationsUtils.clone(property, isOpenAPI31Filter());
    
    				clone.$ref(null);
    				
    				clone.addAnyOfItem(new Schema(property.getSpecVersion()).$ref(property.get$ref()));
    				clone.addAnyOfItem(new NullSchema(property.getSpecVersion()));
    
    				return Optional.of(clone);
    			} else {
    				Schema clone = AnnotationsUtils.clone(property, isOpenAPI31Filter());
    				if (!clone.getTypes().contains("null")) {
    					clone.addType("null");
    				}
    				return Optional.of(clone);
    			}
    		} else {
    			return super.filterSchemaProperty(property, schema, propName, params, cookies, headers);
    		}
    	}
    	
    	@Override
    	public boolean isOpenAPI31Filter() {
    		return true;
    	}
    
    	public static class NullSchema extends Schema {
    
    		public NullSchema(SpecVersion specVersion) {
    			super("null", null, specVersion);
    		}
    
    	}
    	
    }
  2. zeldigas commented on Jun 13, 2024

    @zeldigas
    Contributor

    @karlvr how do you apply this filter?

  3. karlvr commented on Jul 9, 2024

    @karlvr
    Author

    @zeldigas sorry for the slow reply, like this in my class that extends javax.ws.rs.core.Application:

    OpenAPI oas = new OpenAPI();
    ...
    SwaggerConfiguration oasConfig = new SwaggerConfiguration();
    oasConfig.setOpenAPI(oas);
    oasConfig.openAPI31(true); /* Required so that descriptions on properties that turn into $refs stay on the property */
    oasConfig.setFilterClass(NullableToOpenAPI31Filter.class.getName());
    
    try {
    	new JaxrsOpenApiContextBuilder()
    			.servletConfig(servletConfig)
    			.application(this)
    			.openApiConfiguration(oasConfig)
    			.buildContext(true);
    } catch (OpenApiConfigurationException e) {
    	throw new RuntimeException(e.getMessage(), e);
    }
  4. squinker commented on Aug 26, 2025

    @squinker

    Does the Schema annotation have the capability to express this yet?

    allOf:
      - $ref: '#/...'
      - { type: "null" }
    
  5. added a commit that references this issue on Feb 20, 2026
  6. ewaostrowska commented on Feb 20, 2026

    @ewaostrowska
    Contributor

    Hi! This issues should be resolved with #5018 and it will be part of the next release :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions