Published 2026-08-10 by Shubham Bhati — Backend Engineer (Java 17, Spring Boot, Microservices).
As a backend engineer, I've seen the chaos: new team members struggling to onboard, frontend developers guessing API contracts, and integration partners hitting roadblocks because nobody knows what an endpoint expects. Undocumented or poorly documented APIs in a Spring Boot microservice architecture are a silent killer of productivity. This isn't just an annoyance; it’s a production problem causing delays and bugs. Fortunately, there's a powerful antidote: OpenAPI 3 with Swagger UI in Spring Boot. It transforms guesswork into clarity, providing an interactive and auto-generated API specification that anyone can understand and use. Let's make API documentation a strength, not a weakness.
Getting Started: Integrating Springdoc-OpenAPI
Integrating OpenAPI 3 into your Spring Boot application is straightforward, thanks to the springdoc-openapi library. This library reads your Spring annotations and automatically generates an OpenAPI specification, which Swagger UI then renders into a beautiful interactive web page.
To get started, simply add the appropriate dependency to your pom.xml for Maven or build.gradle for Gradle. For a standard Spring Boot Web MVC application, you'll want springdoc-openapi-starter-webmvc-ui:
<!-- Maven -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.3.0</version> <!-- Use the latest stable version -->
</dependency>
// Gradle
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0' // Use the latest stable version
After adding this, restart your application, and Swagger UI will be accessible at /swagger-ui.html and the OpenAPI spec at /v3/api-docs. You can customize basic properties in your application.yaml to give your documentation a title and description:
# application.yaml
springdoc:
swagger-ui:
path: /api-docs # Custom path for Swagger UI
api-docs:
path: /v3/api-docs # Default path for OpenAPI JSON
info:
title: My Microservice API
version: 1.0.0
description: APIs for managing users and products in the My Microservice application.
Production Note: While adding springdoc dependencies does slightly increase your build time and final JAR size, its runtime memory footprint is minimal. The generated OpenAPI spec is mostly static data served on demand, not impacting your core application's HikariCP connection pool or critical business logic latency. The performance overhead is negligible, making it safe for production deployments behind a secure gateway.
Documenting Your Endpoints with Annotations
The real power of springdoc-openapi comes from its ability to interpret standard JAX-RS and Spring Web annotations (@RestController, @RequestMapping, etc.) and enhance them with OpenAPI-specific annotations. This allows you to document your API directly within your code, keeping documentation in sync with your implementation.
Key annotations include:
-
@Tag: To group related operations. -
@Operation: To describe a specific API operation, including a summary and description. -
@Parameter: To document path, query, header or cookie parameters. -
@RequestBody: To describe the request body, including its content type and example. -
@ApiResponse: To define possible responses for an operation, including HTTP status codes and response bodies.
Here's an example of a simple UserController enhanced with these annotations:
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.tags.Tag;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/users")
@Tag(name = "User Management", description = "Operations related to user accounts")
public class UserController {
@Operation(summary = "Get user by ID", description = "Retrieve a single user's details based on their unique identifier.")
@ApiResponse(responseCode = "200", description = "User found successfully",
content = @Content(schema = @Schema(implementation = User.class)))
@ApiResponse(responseCode = "404", description = "User not found")
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(
@Parameter(description = "ID of the user to retrieve", required = true)
@PathVariable Long id) {
// ... implementation
return ResponseEntity.ok(new User(id, "Shubham Bhati"));
}
// Dummy User class for demonstration
static class User {
public Long id;
public String name;
public User(Long id, String name) { this.id = id; this.name = name; }
}
}
Production Note: Accurate API documentation directly reduces latency for integrating teams. Misleading docs, however, lead to p99 spikes in developer frustration and can cause incorrect client implementations that manifest as production bugs. Treat documentation as carefully as your business logic to keep your microservices communicating effectively. Tools like OpenAPI allow you to keep documentation closer to code, making it easier to maintain accuracy.
Securing Swagger UI in Production Environments
While immensely useful for development and testing, exposing Swagger UI without authentication in a production environment is a serious security risk. It can reveal your entire API surface, including internal endpoints and data models, which could be exploited. It's crucial to secure these endpoints properly.
The most common approach is to integrate Spring Security to protect /swagger-ui.html and /v3/api-docs. You can configure basic authentication, integrate with an OAuth2 provider, or restrict access based on IP addresses or roles.
Here’s a conceptual example using Spring Security to protect Swagger UI endpoints:
// Spring Security Configuration
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/api-docs/**", "/swagger-ui/**", "/v3/api-docs/**").authenticated() // Secure Swagger UI paths
.anyRequest().permitAll() // Allow all other requests (adjust as needed for your application)
)
.httpBasic(); // Use basic authentication
// .formLogin(); // Or use form-based login
return http.build();
}
}
This example uses HTTP Basic authentication. For internal tools, this might suffice. For more complex scenarios, consider integrating with your existing identity provider using OAuth2. Alternatively, for critical production systems, you might disable Swagger UI entirely for external access and host a static version of your OpenAPI spec on a separate, secure portal.
Production Note: Exposing Swagger UI without authentication in a production environment is a serious security risk. While the application's memory footprint isn't affected by UI access, a compromise could expose sensitive API endpoints and data models. Always secure /swagger-ui.html and /v3/api-docs using Spring Security, typically behind an internal network or VPN, or with strong authentication. Consider disabling it entirely for external-facing production instances where documentation can be hosted separately and securely.
Common Pitfalls
- Insecure Exposure: The biggest mistake is leaving Swagger UI accessible to the public without any authentication. Always secure
/swagger-ui.htmland/v3/api-docsendpoints in non-development environments. - Outdated Documentation: Code changes but documentation doesn't. Developers forget to update annotations, leading to misleading information. Implement CI/CD checks for documentation consistency or treat OpenAPI annotations as part of the code review process.
- Over-documenting Trivialities: Not every getter/setter needs an extensive description. Focus on what's critical for consumers: inputs, outputs, error conditions. Avoid verbose descriptions that add little value.
- Inconsistent Annotation Usage: Without guidelines, different teams or developers might use annotations inconsistently. Establish clear conventions for
@Tag,@Operation,@ApiResponseto maintain a unified and readable API documentation across your microservices.
Conclusion
API documentation using OpenAPI 3 and Swagger in Spring Boot is more than a convenience; it's a critical component for effective microservices communication and developer productivity. By adopting springdoc-openapi, you transform unclear API contracts into interactive, up-to-date specifications. This improves developer onboarding, reduces integration headaches, and prevents production issues stemming from misunderstandings. Start documenting your APIs today to foster clarity, collaboration, and confidence in your services.
Further Reading
Written by **Shubham Bhati* — Backend Engineer at AlignBits LLC, specializing in Java 17, Spring Boot, microservices, and AI integration. Connect on LinkedIn, GitHub, or read more at shubh2-0.github.io.*
Top comments (0)