A Comprehensive Guide to Spring Boot & Swagger (OpenAPI) Integration
-
Jason Yang - 22 Nov, 2025
- Updated 04 Jan, 2026
- Views —
1. Adding Dependencies
First, add the necessary springdoc-openapi dependencies to your pom.xml file.
springdoc-openapi-starter-webmvc-ui: This is the core library that automatically generates the OpenAPI 3.0 specification by analyzing your Spring Boot application. It also provides the embedded Swagger UI.**springdoc-openapi-maven-plugin**: (Optional) This plugin extracts the API documentation into a static file (e.g.,openapi.json) during the Maven build process. It’s useful for CI/CD pipelines, sharing API specs with other teams, or generating client-side code.
<dependencies>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.5.0</version> </dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-maven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>generate-openapi-spec</id>
<phase>integration-test</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<apiDocsUrl>http://localhost:8080/v3/api-docs</apiDocsUrl>
<outputFileName>openapi.json</outputFileName>
<outputDir>${project.build.directory}</outputDir>
</configuration>
</plugin>
</plugins>
</build>
2. Basic Swagger & JWT Authentication Configuration
To properly document and test your APIs, especially those requiring authentication, you need to configure Swagger. If you use JWT (JSON Web Token) based authentication, it’s crucial to add a UI component that allows users to input their authentication token.
Create a SwaggerConfig class to manage global OpenAPI settings.
// SwaggerConfig.java
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SwaggerConfig {
@Bean
public OpenAPI openAPI() {
// Define API metadata
Info info = new Info()
.title("User Service API")
.description("API documentation for the User Service features.")
.version("v1.0.0");
// Define the security scheme (JWT Bearer Token)
// "bearerAuth" is an arbitrary name,
// but it must be used in the SecurityRequirement.
SecurityScheme securityScheme = new SecurityScheme()
.type(SecurityScheme.Type.HTTP).scheme("bearer").bearerFormat("JWT")
.in(SecurityScheme.In.HEADER).name("Authorization");
// Define the security requirement
// This applies authentication globally to all APIs.
SecurityRequirement securityRequirement = new SecurityRequirement()
.addList("bearerAuth");
return new OpenAPI()
.components(new Components()
.addSecuritySchemes("bearerAuth", securityScheme))
.addSecurityItem(securityRequirement)
.info(info);
}
}
Configuration Explained:
Info: Defines the metadata for your API documentation, such as the title, description, and version.**SecurityScheme**: Defines the authentication method. Here, we’ve configured theBearer Tokenmethod, which uses theAuthorizationheader.**SecurityRequirement**: Defines the security requirements for your APIs. By using.addSecurityItem(), we apply this authentication setting globally to all endpoints.@Configuration: Marks this class as a Spring configuration file.
This setup adds an “Authorize” button to the top-right corner of the Swagger UI. Clicking it will open a dialog where you can enter a JWT (including the Bearer prefix), allowing you to test secured endpoints successfully.
3. Configuring application.yml
You can fine-tune the behavior of Swagger UI in your application.yml file.
# application.yml
springdoc:
swagger-ui:
# The path for the Swagger UI page
path: /swagger-ui.html
# The sorting order for API endpoints (method: by HTTP method, alpha: alphabetically)
operations-sorter: method
# The sorting order for tags (controllers)
tags-sorter: alpha
# Disable the default API docs URL
disable-swagger-default-url: true
api-docs:
# The path for the API documentation (JSON)
path: /v3/api-docs
4. Spring Security Configuration
If you are using Spring Security, you must permit access to the Swagger UI-related paths. Otherwise, you will encounter a 403 Forbidden error and be unable to access the UI.
// SpringSecurityConfig.java
@Configuration
@EnableMethodSecurity // In Spring Security 6.1+, this is included in @EnableWebSecurity
@AllArgsConstructor
public class SpringSecurityConfig {
private final FirebaseAuthenticationFilter firebaseAuthenticationFilter;
@Bean
public static PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity)
throws Exception {
httpSecurity
.csrf(csrf -> csrf.disable()) // Disable CSRF protection
.sessionManagement(session ->
// Use stateless sessions
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth
// Permit access to Swagger UI
.requestMatchers(
"/swagger-ui/**",
"/swagger-ui.html",
"/v3/api-docs/**"
).permitAll()
// Permit specific paths like signup/login without authentication
.requestMatchers(
"/api/v1/auth/**"
).permitAll()
// Require authentication for all other requests
.anyRequest().authenticated()
);
// Add our custom Firebase auth filter before
// the standard UsernamePasswordAuthenticationFilter
httpSecurity.addFilterBefore(firebaseAuthenticationFilter,
UsernamePasswordAuthenticationFilter.class);
return httpSecurity.build();
}
}
5. Documenting APIs with Annotations
Use annotations in your controllers and DTOs to make your API documentation more detailed and clear.
@Tag: Defines a name and description for a controller group (a collection of APIs).@Operation: Adds a summary and a detailed description for each API endpoint.@ApiResponses,@ApiResponse: Specifies the possible response codes (e.g., 200, 404, 500) and their meanings.@Parameter: Defines the description, required status, and example for a request parameter.@Schema: Used to add descriptions or example values for DTOs (Data Transfer Objects) or model objects.
// UserController.java
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
@Tag(name = "User", description = "User management APIs")
@RestController
@RequestMapping("/api/v1/users")
@AllArgsConstructor
public class UserController {
private static final Logger log = LoggerFactory.getLogger(UserController.class);
private final UserService userService;
@Operation(summary = "User Signup", description = "Creates a new user and registers them in the system.")
@ApiResponses({
@ApiResponse(responseCode = "201", description = "Signup successful", content = @Content(schema = @Schema(implementation = UserDto.class))),
@ApiResponse(responseCode = "400", description = "Invalid request format."),
@ApiResponse(responseCode = "409", description = "User already exists (email conflict).")
})
@PostMapping
public ResponseEntity<UserDto> createUser(
@Parameter(description = "User information required for signup", required = true, schema = @Schema(implementation = UserDto.class))
@RequestBody UserDto userDto
) {
log.info("Received signup request: {}", userDto);
try {
UserDto created = userService.addUser(userDto);
log.info("Signup successful: {}", created);
return ResponseEntity.status(HttpStatus.CREATED).body(created);
} catch (Exception e) {
log.error("Error during signup: {}", e.getMessage(), e);
throw e;
}
}
}
6. Accessing the Swagger UI & API Docs
After running your application, you can access the generated API documentation and UI at the following URLs:
- Swagger UI:
http://localhost:8080/swagger-ui.html - OpenAPI Docs (JSON):
http://localhost:8080/v3/api-docs
7. Best Practices for API Documentation
- Add Clear Descriptions for All APIs: In
@Operation, usesummaryfor a concise description of what the API does anddescriptionfor additional details or constraints. - Explicitly Mark Secured APIs: Besides the global setting, you can require authentication for a specific API by adding
@SecurityRequirement(name = "bearerAuth")to its method. - Include Request/Response Examples: Add annotations like
@Schema(description = "User's name", example = "John Doe")to fields in your DTO classes. This greatly improves readability by showing example values in the API documentation. - Document All Possible Error Responses: Use
@ApiResponsesto specify not only success cases (2xx) but also all expected failure cases (4xx, 5xx) and their causes. - Manage API Versions: When the API specification changes, update the
.version()information in yourSwaggerConfigto maintain a history of changes.
8. Security Considerations
- Restrict Access in Production: For security reasons, you must disable the Swagger UI page or restrict access to it in your production environment. This can be done by limiting access to specific IP addresses or users with a certain role (e.g., ADMIN). You can also use Spring Profiles (
@Profile("!prod")) to prevent Swagger-related beans from being created in production. - Manage Authentication Information: Be careful not to expose authentication tokens used for API testing.
- Minimize Information Exposure: Design your DTOs carefully to avoid including sensitive information (personal data, internal system paths, etc.) in API responses.