Search code examples
javarestswagger

How to set a default custom schema for types in Swagger


There is a way to define a custom schema as default for a Java Class in Swagger?

You can set the schema with annotations like this:

schema = @Schema(type = "string", format = "<custom-format>", example = "<custom-example>"))

But I want to assign this schema to a Java Class as default, so I don't need to add schema annotations always I define this data type on API.


Update

Default schema types are defined in https://github.com/swagger-api/swagger-core/blob/master/modules/swagger-core/src/main/java/io/swagger/v3/core/util/PrimitiveType.java

There is a way to override or extend this?


Solution

    1. Create a custom ModelConverter:
    import java.lang.reflect.Type;
    import java.time.YearMonth;
    import java.util.Iterator;
    
    import com.fasterxml.jackson.databind.type.SimpleType;
    
    import io.swagger.v3.core.converter.AnnotatedType;
    import io.swagger.v3.core.converter.ModelConverter;
    import io.swagger.v3.core.converter.ModelConverterContext;
    import io.swagger.v3.oas.models.media.Schema;
    
    /*
    * Custom ModelConverter that create a custom schema for YearMonth types
    */
    public class CustomModelConverter implements ModelConverter {
        private static final Schema SCHEMA_YEAR_MONTH = new Schema().type("string").format("year-month").example("2020-06");
    
        @Override
        public Schema resolve(AnnotatedType annotatedType, ModelConverterContext context, Iterator<ModelConverter> chain) {
            Type type = annotatedType.getType();
            if (type instanceof SimpleType) {
                SimpleType simpleType = (SimpleType) type;
    
                if (YearMonth.class.isAssignableFrom(simpleType.getRawClass())) {
                    return SCHEMA_YEAR_MONTH;
                }
            }
    
            // It's needed to follow chain for unresolved types
            if (chain.hasNext()) {
                return chain.next().resolve(annotatedType, context, chain);
            }
            return null;
        }
    }
    
    1. Register your custom ModelConverter:
    ModelConverters.getInstance().addConverter(new CustomModelConverter());
    

    Suggestion: put this as static initializer block on JAX-RS Activator