Customize Model in Swagger

Change model request and response definitions in a Java-based Swagger setup using Springfox model plugins.

When using Springfox to generate Swagger documentation for your Spring REST API, the default model definitions may not always match what you want to expose. Springfox provides ModelPropertyBuilderPlugin and ModelBuilderPlugin to let you customize how models and their properties appear in the Swagger UI.

Why Customize Models?

Common reasons to customize your Swagger models:

  • Hide internal fields (passwords, audit columns) from the API docs
  • Add example values to properties
  • Change the displayed type (e.g., show a Long as string for IDs)
  • Add custom descriptions or validation annotations
  • Show different models for request vs. response

Using ModelPropertyBuilderPlugin

The ModelPropertyBuilderPlugin lets you modify individual properties of a model. Implement the supports and apply methods:

import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.schema.ModelPropertyBuilderPlugin;
import springfox.documentation.schema.ModelPropertyBuilder;
import springfox.documentation.spi.schema.contexts.ModelPropertyContext;

@Component
@Order(Ordered.LAST)
public class CustomModelPropertyPlugin implements ModelPropertyBuilderPlugin {

    @Override
    public boolean supports(DocumentationType delimiter) {
        return true;
    }

    @Override
    public void apply(ModelPropertyContext context) {
        // Add a description to specific fields
        context.getBeanPropertyDefinition()
            .ifPresent(property -> {
                String name = property.getName();
                if ("id".equals(name)) {
                    context.getBuilder()
                        .description("Unique identifier")
                        .example("550e8400-e29b-41d4-a716-446655440000")
                        .type(new TypeResolver().resolve(String.class));
                }
            });

        // Hide fields annotated with @ApiHide
        context.getBeanPropertyDefinition()
            .ifPresent(property -> {
                if (property.getField() != null
                        && property.getField().getAnnotation(ApiHide.class) != null) {
                    context.getBuilder().hidden(true);
                }
            });
    }
}

Using ModelBuilderPlugin

The ModelBuilderPlugin lets you customize the model as a whole — for example, changing the description or ID of the model:

import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.schema.ModelBuilderPlugin;
import springfox.documentation.spi.schema.contexts.ModelContext;
import springfox.documentation.schema.Model;

@Component
public class CustomModelPlugin implements ModelBuilderPlugin {

    @Override
    public boolean supports(DocumentationType delimiter) {
        return true;
    }

    @Override
    public void apply(ModelContext context) {
        // Set a custom description for specific models
        if (context.getType().getErasedType().equals(User.class)) {
            context.getBuilder()
                .description("User account information");
        }
    }
}

Different Request vs. Response Models

One of the most common customizations is showing different fields in request and response. For example, you might want to exclude id from create requests but include it in responses.

Springfox uses ModelContext to determine whether the model is for a request or response:

@Override
public void apply(ModelPropertyContext context) {
    ModelContext modelContext = (ModelContext) context.getParent();

    // Check if this is a request (input) or response (output) model
    boolean isResponse = modelContext.isReturnType();

    context.getBeanPropertyDefinition().ifPresent(property -> {
        String name = property.getName();
        if ("id".equals(name) && !isResponse) {
            context.getBuilder().hidden(true);
        }
    });
}

Annotation-Based Hiding

Create a custom annotation to mark fields that should be hidden from Swagger:

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiHide {
}

Then in your model:

public class User {
    private String id;
    private String name;

    @ApiHide
    private String internalNote;  // Won't appear in Swagger docs

    // getters and setters
}

And in your ModelPropertyBuilderPlugin:

@Override
public void apply(ModelPropertyContext context) {
    context.getBeanPropertyDefinition().ifPresent(property -> {
        if (property.getField().getAnnotation(ApiHide.class) != null) {
            context.getBuilder().hidden(true);
        }
    });
}

Registering Plugins

Spring Boot will auto-detect your plugin if it’s annotated with @Component. Make sure your configuration class scans the package:

@Configuration
@ComponentScan("com.example.swagger")
public class SwaggerConfig {
    // ...
}

External Resources