Java library that automates OpenAPI 3 documentation generation for Spring Boot applications with seamless Swagger UI integration
—
Core SpringDoc functionality that automatically discovers Spring REST endpoints and generates OpenAPI 3 specifications. This system examines Spring Boot applications at runtime to create comprehensive API documentation without manual configuration.
Main configuration class that sets up the core OpenAPI document generation infrastructure.
/**
* Core configuration class for SpringDoc OpenAPI document generation
* Provides essential beans for API discovery and documentation generation
*/
@Configuration
@ConditionalOnProperty(name = "springdoc.api-docs.enabled", matchIfMissing = true)
@ConditionalOnBean(OpenAPI.class)
public class SpringDocConfiguration {
/**
* Creates OpenAPI resource for serving API documentation
* @param openAPI OpenAPI specification builder
* @param springDocConfigProperties Configuration properties
* @param operationService Service for operation metadata
* @param requestMappingInfoHandlerMapping Handler mapping for endpoints
* @param actuatorProvider Optional actuator integration
* @return OpenApiResource instance for API documentation serving
*/
@Bean
@ConditionalOnMissingBean
public OpenApiResource openApiResource(OpenAPI openAPI,
SpringDocConfigProperties springDocConfigProperties,
OperationService operationService,
RequestMappingInfoHandlerMapping requestMappingInfoHandlerMapping,
Optional<ActuatorProvider> actuatorProvider);
/**
* Creates operation service for analyzing REST endpoints
* @param genericParameterService Service for parameter analysis
* @param operationCustomizers List of operation customizers
* @param propertyResolverUtils Property resolution utilities
* @param springDocConfigProperties Configuration properties
* @return OperationService for endpoint analysis
*/
@Bean
@ConditionalOnMissingBean
public OperationService operationService(GenericParameterService genericParameterService,
List<OperationCustomizer> operationCustomizers, PropertyResolverUtils propertyResolverUtils,
SpringDocConfigProperties springDocConfigProperties);
/**
* Creates request builder for analyzing request parameters
* @param genericParameterService Parameter analysis service
* @param requestBodyService Request body analysis service
* @param operationService Operation metadata service
* @param parameterCustomizers List of parameter customizers
* @param localSpringDocParameterNameDiscoverer Parameter name discovery
* @return RequestBuilder for request analysis
*/
@Bean
@ConditionalOnMissingBean
public RequestBuilder requestBuilder(GenericParameterService genericParameterService,
RequestBodyBuilder requestBodyService, OperationService operationService,
List<ParameterCustomizer> parameterCustomizers,
LocalSpringDocParameterNameDiscoverer localSpringDocParameterNameDiscoverer);
/**
* Creates response builder for analyzing response types
* @param operationService Operation metadata service
* @param returnTypeCustomizers List of return type customizers
* @param springDocConfigProperties Configuration properties
* @param propertyResolverUtils Property resolution utilities
* @return ResponseBuilder for response analysis
*/
@Bean
@ConditionalOnMissingBean
public ResponseBuilder responseBuilder(OperationService operationService,
List<ReturnTypeCustomizer> returnTypeCustomizers, SpringDocConfigProperties springDocConfigProperties,
PropertyResolverUtils propertyResolverUtils);
}Configuration properties that control OpenAPI document generation behavior.
/**
* Configuration properties for SpringDoc OpenAPI generation
* Controls API discovery, filtering, and output formatting
*/
@ConfigurationProperties("springdoc")
public class SpringDocConfigProperties {
/**
* Default constructor
*/
public SpringDocConfigProperties();
/**
* Path where OpenAPI JSON documentation is served
* @return API docs path (default: /v3/api-docs)
*/
public String getApiDocsPath();
public void setApiDocsPath(String apiDocsPath);
/**
* Whether OpenAPI documentation generation is enabled
* @return true if enabled (default: true)
*/
public boolean isEnabled();
public void setEnabled(boolean enabled);
/**
* Packages to scan for REST controllers
* @return comma-separated package names to include
*/
public String getPackagesToScan();
public void setPackagesToScan(String packagesToScan);
/**
* URL patterns to include in documentation
* @return comma-separated path patterns to match
*/
public String getPathsToMatch();
public void setPathsToMatch(String pathsToMatch);
/**
* Packages to exclude from scanning
* @return comma-separated package names to exclude
*/
public String getPackagesToExclude();
public void setPackagesToExclude(String packagesToExclude);
/**
* URL patterns to exclude from documentation
* @return comma-separated path patterns to exclude
*/
public String getPathsToExclude();
public void setPathsToExclude(String pathsToExclude);
/**
* Whether to show Spring Boot Actuator endpoints
* @return true to include actuator endpoints
*/
public boolean isShowActuator();
public void setShowActuator(boolean showActuator);
/**
* Whether to use management port for API documentation
* @return true to serve docs on management port
*/
public boolean isUseManagementPort();
public void setUseManagementPort(boolean useManagementPort);
/**
* Cache settings for API documentation
* @return cache configuration
*/
public Cache getCache();
public void setCache(Cache cache);
/**
* API groups configuration for multi-API documentation
* @return list of API group configurations
*/
public List<GroupConfig> getGroupConfigs();
public void setGroupConfigs(List<GroupConfig> groupConfigs);
/**
* Default produces media types for operations without explicit @Produces
* @return array of media type strings
*/
public String[] getDefaultProducesMediaTypes();
public void setDefaultProducesMediaTypes(String[] defaultProducesMediaTypes);
/**
* Default consumes media types for operations without explicit @Consumes
* @return array of media type strings
*/
public String[] getDefaultConsumesMediaTypes();
public void setDefaultConsumesMediaTypes(String[] defaultConsumesMediaTypes);
/**
* Whether to override existing operation information
* @return true to override existing operation data
*/
public boolean isOverrideWithGenericResponse();
public void setOverrideWithGenericResponse(boolean overrideWithGenericResponse);
/**
* Whether to remove broken reference definitions
* @return true to clean up broken references
*/
public boolean isRemoveBrokenReferenceDefinitions();
public void setRemoveBrokenReferenceDefinitions(boolean removeBrokenReferenceDefinitions);
/**
* Writer with default pretty printer configuration
* @return writer configuration
*/
public WriterWithDefaultPrettyPrinter getWriterWithDefaultPrettyPrinter();
public void setWriterWithDefaultPrettyPrinter(WriterWithDefaultPrettyPrinter writerWithDefaultPrettyPrinter);
/**
* Nested cache configuration class
*/
public static class Cache {
private boolean disabled = false;
public boolean isDisabled();
public void setDisabled(boolean disabled);
}
/**
* Nested API group configuration class
*/
public static class GroupConfig {
private String group;
private String displayName;
private String[] packagesToScan;
private String[] pathsToMatch;
private String[] packagesToExclude;
private String[] pathsToExclude;
public String getGroup();
public void setGroup(String group);
public String getDisplayName();
public void setDisplayName(String displayName);
public String[] getPackagesToScan();
public void setPackagesToScan(String[] packagesToScan);
public String[] getPathsToMatch();
public void setPathsToMatch(String[] pathsToMatch);
public String[] getPackagesToExclude();
public void setPackagesToExclude(String[] packagesToExclude);
public String[] getPathsToExclude();
public void setPathsToExclude(String[] pathsToExclude);
}
}REST controller that serves the generated OpenAPI documentation in JSON and YAML formats.
/**
* REST controller serving OpenAPI specification documents
* Provides generated API documentation in multiple formats
*/
@RestController
public class OpenApiResource {
/**
* Constructor for OpenAPI resource controller
* @param openAPI OpenAPI specification object
* @param springDocConfigProperties Configuration properties
* @param operationService Service for operation processing
* @param requestMappingInfoHandlerMapping Spring MVC handler mapping
* @param actuatorProvider Optional actuator integration
*/
public OpenApiResource(OpenAPI openAPI, SpringDocConfigProperties springDocConfigProperties,
OperationService operationService, RequestMappingInfoHandlerMapping requestMappingInfoHandlerMapping,
Optional<ActuatorProvider> actuatorProvider);
/**
* Returns OpenAPI specification in JSON format
* @param request HTTP request for context
* @param locale Locale for internationalization
* @return OpenAPI specification as JSON string
* @throws JsonProcessingException if JSON serialization fails
*/
@Operation(hidden = true)
@GetMapping(value = "${springdoc.api-docs.path:/v3/api-docs}",
produces = MediaType.APPLICATION_JSON_VALUE)
public String openapiJson(HttpServletRequest request, Locale locale)
throws JsonProcessingException;
/**
* Returns OpenAPI specification in YAML format
* @param request HTTP request for context
* @param locale Locale for internationalization
* @return OpenAPI specification as YAML string
* @throws JsonProcessingException if YAML serialization fails
*/
@Operation(hidden = true)
@GetMapping(value = "${springdoc.api-docs.path:/v3/api-docs}.yaml",
produces = "application/vnd.oai.openapi")
public String openapiYaml(HttpServletRequest request, Locale locale)
throws JsonProcessingException;
/**
* Returns OpenAPI specification for specific API group in JSON format
* @param group API group name
* @param request HTTP request for context
* @param locale Locale for internationalization
* @return Group-specific OpenAPI specification as JSON
* @throws JsonProcessingException if JSON serialization fails
*/
@Operation(hidden = true)
@GetMapping(value = "${springdoc.api-docs.path:/v3/api-docs}/{group}",
produces = MediaType.APPLICATION_JSON_VALUE)
public String openapiJson(@PathVariable String group, HttpServletRequest request,
Locale locale) throws JsonProcessingException;
/**
* Returns OpenAPI specification for specific API group in YAML format
* @param group API group name
* @param request HTTP request for context
* @param locale Locale for internationalization
* @return Group-specific OpenAPI specification as YAML
* @throws JsonProcessingException if YAML serialization fails
*/
@Operation(hidden = true)
@GetMapping(value = "${springdoc.api-docs.path:/v3/api-docs}/{group}.yaml",
produces = "application/vnd.oai.openapi")
public String openapiYaml(@PathVariable String group, HttpServletRequest request,
Locale locale) throws JsonProcessingException;
/**
* Builds OpenAPI specification for the given request context
* @param request HTTP request providing context information
* @param locale Locale for localized documentation
* @return Complete OpenAPI specification object
*/
protected OpenAPI getOpenApi(HttpServletRequest request, Locale locale);
/**
* Calculates server URLs for the OpenAPI specification
* @param request HTTP request for URL calculation
* @param locale Locale context
* @return OpenAPI object with calculated server URLs
*/
protected OpenAPI calculateServerUrl(HttpServletRequest request, Locale locale);
}Service that analyzes Spring MVC operations and generates OpenAPI operation definitions.
/**
* Service for analyzing Spring MVC operations and generating OpenAPI definitions
* Core component that processes REST controller methods
*/
public class OperationService {
/**
* Constructor for operation analysis service
* @param genericParameterService Service for parameter type analysis
* @param operationCustomizers List of operation customization handlers
* @param propertyResolverUtils Utilities for property resolution
* @param springDocConfigProperties Configuration properties
*/
public OperationService(GenericParameterService genericParameterService,
List<OperationCustomizer> operationCustomizers, PropertyResolverUtils propertyResolverUtils,
SpringDocConfigProperties springDocConfigProperties);
/**
* Builds OpenAPI operation from Spring MVC handler method
* @param handlerMethod Spring MVC handler method
* @param requestMethod HTTP request method
* @param operation Existing operation to enhance
* @param methodAttributes Method-level attributes
* @param openAPI OpenAPI context object
* @return Enhanced Operation object with complete metadata
*/
public Operation buildOperation(HandlerMethod handlerMethod, RequestMethod requestMethod,
Operation operation, MethodAttributes methodAttributes, OpenAPI openAPI);
/**
* Gets operation tags from method annotations
* @param handlerMethod Spring MVC handler method
* @param operation Operation object to populate
* @param locale Locale for localized tags
*/
public void buildTags(HandlerMethod handlerMethod, Operation operation, Locale locale);
/**
* Processes operation customizers for the given operation
* @param operation Operation to customize
* @param handlerMethod Spring MVC handler method
* @return Customized Operation object
*/
public Operation customizeOperation(Operation operation, HandlerMethod handlerMethod);
/**
* Determines if operation should be hidden from documentation
* @param handlerMethod Spring MVC handler method
* @return true if operation should be excluded from documentation
*/
public boolean isHidden(HandlerMethod handlerMethod);
/**
* Gets operation ID from method or generates unique identifier
* @param handlerMethod Spring MVC handler method
* @return Unique operation identifier
*/
public String getOperationId(HandlerMethod handlerMethod);
/**
* Builds operation summary from annotations or method name
* @param operation Operation object to populate
* @param handlerMethod Spring MVC handler method
*/
public void buildOperationSummary(Operation operation, HandlerMethod handlerMethod);
/**
* Builds operation description from annotations
* @param operation Operation object to populate
* @param handlerMethod Spring MVC handler method
*/
public void buildOperationDescription(Operation operation, HandlerMethod handlerMethod);
/**
* Processes security requirements for the operation
* @param operation Operation object to populate
* @param handlerMethod Spring MVC handler method
*/
public void buildSecurityRequirements(Operation operation, HandlerMethod handlerMethod);
}SpringDoc automatically discovers and documents REST endpoints:
@RestController
@RequestMapping("/api/users")
public class UserController {
// This endpoint is automatically documented
@GetMapping
public List<User> getAllUsers() {
return userService.findAll();
}
// SpringDoc generates schema from User class and validation annotations
@PostMapping
public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
User created = userService.save(user);
return ResponseEntity.status(201).body(created);
}
}
// Model class with validation annotations automatically documented
public class User {
@NotNull
@Size(min = 1, max = 50)
private String username;
@Email
private String email;
@Min(18)
private Integer age;
// Getters and setters...
}Add OpenAPI annotations for comprehensive documentation:
@RestController
@RequestMapping("/api/products")
@Tag(name = "Product Management", description = "Operations for managing products")
public class ProductController {
@GetMapping("/{id}")
@Operation(
summary = "Get product by ID",
description = "Retrieves a single product by its unique identifier",
responses = {
@ApiResponse(responseCode = "200", description = "Product found",
content = @Content(schema = @Schema(implementation = Product.class))),
@ApiResponse(responseCode = "404", description = "Product not found")
}
)
public ResponseEntity<Product> getProduct(
@Parameter(description = "Product ID", example = "12345")
@PathVariable Long id) {
return productService.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@PostMapping
@Operation(summary = "Create new product")
@SecurityRequirement(name = "bearerAuth")
public ResponseEntity<Product> createProduct(
@Parameter(description = "Product to create")
@Valid @RequestBody CreateProductRequest request) {
Product created = productService.create(request);
return ResponseEntity.status(201).body(created);
}
}Control which APIs are documented through configuration:
springdoc:
api-docs:
enabled: true
path: /v3/api-docs
packages-to-scan: com.example.api
paths-to-match: /api/**
paths-to-exclude: /api/internal/**
show-actuator: false// Only controllers in com.example.api package matching /api/**
// (excluding /api/internal/**) will be documented
@RestController
@RequestMapping("/api/public") // Will be documented
public class PublicApiController {
// ...
}
@RestController
@RequestMapping("/api/internal") // Will be excluded
public class InternalApiController {
// ...
}
@RestController
@RequestMapping("/admin") // Will be excluded (doesn't match /api/**)
public class AdminController {
// ...
}Configure multiple API groups for microservice documentation:
springdoc:
group-configs:
- group: public-api
display-name: "Public API"
paths-to-match: /api/public/**
- group: admin-api
display-name: "Admin API"
paths-to-match: /api/admin/**
packages-to-scan: com.example.admin// Access group-specific documentation:
// GET /v3/api-docs/public-api - Public API documentation
// GET /v3/api-docs/admin-api - Admin API documentation
// GET /v3/api-docs - Complete API documentationCustomize the generated OpenAPI specification:
@Configuration
public class OpenApiConfig {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("My API")
.version("1.0")
.description("Comprehensive API for my application")
.contact(new Contact()
.name("API Support")
.email("support@example.com")
.url("https://example.com/support"))
.license(new License()
.name("MIT")
.url("https://opensource.org/licenses/MIT")))
.servers(List.of(
new Server().url("https://api.example.com").description("Production"),
new Server().url("https://staging-api.example.com").description("Staging")
))
.addSecurityItem(new SecurityRequirement().addList("bearerAuth"))
.components(new Components()
.addSecuritySchemes("bearerAuth", new SecurityScheme()
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.bearerFormat("JWT")));
}
@Bean
public OperationCustomizer operationIdCustomizer() {
return (operation, handlerMethod) -> {
String className = handlerMethod.getBeanType().getSimpleName();
String methodName = handlerMethod.getMethod().getName();
operation.setOperationId(className + "_" + methodName);
return operation;
};
}
}SpringDoc supports lazy loading for better startup performance:
springdoc:
api-docs:
enabled: true
lazy-initialization: true
cache:
disabled: false # Enable caching for production# Production configuration
springdoc:
api-docs:
enabled: true # Keep docs enabled
swagger-ui:
enabled: false # Disable UI in production
cache:
disabled: false # Enable caching
writer-with-default-pretty-printer: false # Compact JSON outputFor applications with many endpoints:
springdoc:
packages-to-scan: com.example.api # Limit scanning scope
paths-to-match: /api/** # Filter by path patterns
remove-broken-reference-definitions: true # Clean up unused schemas
override-with-generic-response: false # Avoid generic response pollutionInstall with Tessl CLI
npx tessl i tessl/maven-org-springdoc--springdoc-openapi