Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 66

Documenting REST APIs with Swagger/OpenAPI

Recommended resources

Welcome to your next lesson! In our last session, we put the final piece of the puzzle into our JWT security implementation by creating a validation filter. Your API is now fully secured, requiring a valid token to access protected resources. This is a major milestone. However, an API that no one knows how to use is like a library with no catalog. It's full of valuable resources, but they're difficult to discover and use.

Today, we will address this by learning how to document our REST APIs using Swagger and OpenAPI. We'll see how to automatically generate beautiful, interactive documentation directly from our Java code. This documentation will allow other developers (like a frontend developer on your team, or even your future self) to understand, explore, and test your API endpoints directly in their browser.

By the end of this lesson, you will be able to integrate Swagger UI into your Spring Boot project, configure it to work with our JWT security, and use annotations to create clear, professional API documentation—a crucial skill for any backend developer.

What are OpenAPI and Swagger?

Before we dive into the code, it's important to understand two key terms: OpenAPI and Swagger. They are often used interchangeably, but they have distinct meanings.

  • OpenAPI Specification: This is a standard, a language-agnostic blueprint for describing REST APIs. It defines a formal way to list all your endpoints, their parameters, the data they expect, the responses they return, authentication methods, and more. Think of it as the official rulebook for your API.
  • Swagger: This is a set of tools built around the OpenAPI Specification. The most famous of these tools is Swagger UI, which takes an OpenAPI document and generates an interactive, web-based user interface.

The following short video provides an excellent summary of this relationship and why it's so valuable.

Swagger UI Integration in Spring Boot 3 (Beginner-Friendly)

Watch this brief introduction from the video "Swagger UI Integration in Spring Boot 3".

Pay attention to the explanation from the beginning. It clearly distinguishes the OpenAPI specification from the Swagger toolkit and highlights the benefits for development teams.


Step 1: Integrating SpringDoc and Swagger UI

For modern Spring Boot applications (version 3 and later), the go-to library for integrating OpenAPI is springdoc-openapi. It automatically scans your controllers and generates the OpenAPI specification for you. With just one dependency, we get both the OpenAPI document and the Swagger UI.

Let's add the necessary dependency to your pom.xml file.

Spring boot 3 - OpenApi Documentation | Swagger UI

The video "Spring boot 3 - OpenApi Documentation" clearly explains which dependency is needed for Spring Boot 3 projects.

Watch the segment from this point, where the presenter navigates the SpringDoc documentation and adds the correct dependency to the pom.xml.

Add the following dependency to the <dependencies> section of your pom.xml:

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.3.0</version> <!-- You can check for the latest version -->
</dependency>

After adding the dependency and letting your IDE (like IntelliJ) reload the Maven project, that's it for the initial setup! If you were to run the application without Spring Security, you could immediately access the Swagger UI. However, our application is secured, which leads to our next step.


Step 2: Allowing Access through Spring Security

If you run the application now and try to navigate to http://localhost:8080/swagger-ui/index.html, you will likely be met with a login page or a 403 Forbidden error. This is Spring Security doing its job! Our configuration anyRequest().authenticated() blocks access to everything that isn't explicitly permitted.

We need to update our SecurityConfig to allow anonymous access to the URLs required by Swagger UI.

Spring boot 3 - OpenApi Documentation | Swagger UI

This part of the same video demonstrates exactly how to solve this problem.

Watch the section from this clip, which shows how to add the necessary URL patterns to the security configuration's whitelist.

Open your SecurityConfig.java file and update the securityFilterChain method. Add the Swagger UI and API docs paths to the requestMatchers.

// In SecurityConfig.java

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
        .csrf(AbstractHttpConfigurer::disable)
        .authorizeHttpRequests(auth -> auth
            // Permit access to auth endpoints and Swagger UI
            .requestMatchers(
                "/auth/**",
                "/v2/api-docs",
                "/v3/api-docs",
                "/v3/api-docs/**",
                "/swagger-resources",
                "/swagger-resources/**",
                "/configuration/ui",
                "/configuration/security",
                "/swagger-ui/**",
                "/webjars/**",
                "/swagger-ui.html"
            ).permitAll()
            .anyRequest().authenticated() // Secure all other endpoints
        )
        .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
        .authenticationProvider(authenticationProvider)
        .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);

    return http.build();
}

Now, restart your application. You should be able to access the Swagger UI at http://localhost:8080/swagger-ui/index.html. You will see your API endpoints listed, but we're not done yet. If you try to execute a secured endpoint (like our /api/greetings), it will fail with a 403 Forbidden because the request doesn't include a JWT. Let's fix that.


Step 3: Configuring JWT Authentication in Swagger UI

To use our secured endpoints, Swagger UI needs a way to include the Authorization: Bearer <token> header in its requests. We can configure this by defining a "Security Scheme". This will add a global "Authorize" button to the UI, allowing you to paste a JWT and have it applied to subsequent API calls.

To keep our configuration clean, let's create a dedicated configuration class for OpenAPI.

  1. Create a new class named OpenApiConfig in your config package.
  2. Add the annotations to define the security scheme and apply it globally.

Spring boot 3 - OpenApi Documentation | Swagger UI

This part of the video is crucial. It shows how to add the security configuration that enables JWT authentication within the Swagger UI.

First, watch how the @SecurityScheme is defined from this part. This sets up the "Bearer Auth" mechanism. Then, see how it's applied globally using the security attribute from this section. This ensures the lock icon appears on all endpoints.

Here is the code for your OpenApiConfig.java class:

package com.example.yourproject.config;

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
import io.swagger.v3.oas.annotations.info.Info;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.security.SecurityScheme;

@OpenAPIDefinition(
    info = @Info(
        title = "My Awesome API",
        description = "REST API for my application",
        version = "1.0"
    ),
    security = {
        @SecurityRequirement(name = "bearerAuth")
    }
)
@SecurityScheme(
    name = "bearerAuth",
    description = "JWT auth description",
    scheme = "bearer",
    type = SecuritySchemeType.HTTP,
    bearerFormat = "JWT",
    in = SecuritySchemeIn.HEADER
)
public class OpenApiConfig {
}

Let's break down these annotations:

  • @SecurityScheme: This defines our authentication method.
    • name: bearerAuth (a name we choose).
    • scheme: bearer.
    • type: HTTP, as it's an HTTP header-based authentication.
    • bearerFormat: JWT.
    • in: HEADER, specifying the token is in the request header.
  • @OpenAPIDefinition: This annotation provides global information about your API.
    • info: Sets the title, description, and version.
    • security: The @SecurityRequirement here applies the bearerAuth scheme we just defined to all endpoints globally.

Restart your application and refresh the Swagger UI. You will now see:

  1. A professional-looking title and description for your API.
  2. An "Authorize" button at the top right.
  3. A lock icon next to each of your endpoints.

Now you can test the full flow:

  1. Go to the /auth/login endpoint in Swagger UI, execute it with valid user credentials to get a JWT.
  2. Click the "Authorize" button, paste the token (without the "Bearer " prefix), and click "Authorize".
  3. Now, go to the /api/greetings endpoint and click "Try it out" -> "Execute". It should return a 200 OK with the success message!

Step 4: Enhancing Endpoint Documentation

While our documentation is now functional, it's still quite sparse. The controller is named greetings-controller, and there's no description of what the endpoint does. We can use more annotations to make it much clearer.

Spring boot 3 - OpenApi Documentation | Swagger UI

The final part of the video shows how to "beautify" the documentation using several helpful annotations.

Watch the section from this segment to learn about @Tag for renaming controllers, @Operation for describing endpoints, and @ApiResponse for detailing possible responses.

Let's apply these annotations to our GreetingsController.

// In GreetingsController.java

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/greetings")
@Tag(name = "Greetings", description = "Endpoints for simple greetings")
public class GreetingsController {

    @Operation(
        summary = "Get a secured greeting",
        description = "Returns a simple greeting message. This endpoint is secured and requires a valid JWT token."
    )
    @ApiResponse(responseCode = "200", description = "Successful operation")
    @ApiResponse(responseCode = "403", description = "Forbidden - Invalid or missing JWT token")
    @GetMapping
    public ResponseEntity<String> sayHello() {
        return ResponseEntity.ok("Hello from a secured endpoint!");
    }
}
  • @Tag(name = "..."): This annotation at the class level provides a clean, user-friendly name for the group of endpoints in this controller. Instead of greetings-controller, it will now appear as "Greetings".
  • @Operation(summary = "...", description = "..."): This provides a short summary and a more detailed description for a specific endpoint.
  • @ApiResponse(...): This documents the possible HTTP responses, including success and error codes, making it clear what a consumer of the API can expect.

Restart your application and check the Swagger UI one last time. The "Greetings" endpoint is now much more descriptive and professional.


A Final Note on Security

Exposing interactive API documentation on a production server can be a security risk. It's often best to disable Swagger UI in production environments. You can do this easily by adding the following line to your application-prod.properties file (assuming you use profiles for different environments):

springdoc.swagger-ui.enabled=false

This ensures that while the documentation is available for developers during development, it's not exposed to the public in your live application.


Conclusion

Congratulations! You have successfully integrated a powerful documentation tool into your project. You now have a secure, well-documented REST API that is ready for other developers to use. This is a standard practice in the industry and a valuable skill to have.

Key Takeaways:

  • OpenAPI is the specification; Swagger UI is a tool that creates interactive documentation from it.
  • The springdoc-openapi-starter-webmvc-ui dependency is all you need to get started in Spring Boot 3.
  • You must permit Swagger's URLs in your Spring Security configuration to make the UI accessible.
  • Use @SecurityScheme and @SecurityRequirement to configure Swagger UI for JWT-based authentication.
  • Use annotations like @Tag, @Operation, and @ApiResponse to enrich your documentation and make it easy to understand.

Our API is now secure and documented. The next logical step is to ensure it is robust and reliable. In our next lesson, we will begin exploring the world of testing by writing our first unit tests with JUnit.