Generate REST API Documentation for Spring Boot Using Swagger

In our previous tutorial, we built a Spring Boot CRUD REST API for User Management using Spring Data JPA and MySQL. Now, we will extend that tutorial by generating REST API documentation using Swagger (Springdoc OpenAPI 3).

The prerequisite for this tutorial is you need to first Build RESTful Web Services Using Spring Boot, Spring Data JPA, and MySQL

📌 Benefits of Using Swagger

Automatic API documentation generation.
Interactive UI for testing APIs.
✅ Helps frontend developers understand API contracts.
✅ Supports multiple response types and request schemas.

🚀 Step 1: Add Swagger Dependency

Spring Boot does not include Swagger by default, so we need to add the Springdoc OpenAPI dependency.

📌 Add the following dependency to pom.xml

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.8.3</version>
</dependency>

📌 Explanation

✔️ springdoc-openapi-starter-webmvc-ui → Provides a Swagger UI to interact with REST APIs.
✔️ Version 2.8.3 → Latest stable version for OpenAPI 3.

🚀 Step 2: Enable Swagger in Spring Boot

Spring Boot automatically configures Swagger when the dependency is added, so we don't need additional configuration.

To verify, start your Spring Boot application:

mvn spring-boot:run

Then, open your browser and go to:
👉 Swagger UI: http://localhost:8080/swagger-ui.html
👉 OpenAPI JSON: http://localhost:8080/v3/api-docs

🚀 Step 3: Annotate the REST Controller

To generate API documentation, we use OpenAPI 3 annotations.

📌 Modify UserController.java inside net.javaguides.usermanagement.controller

package net.javaguides.usermanagement.controller;

import io.swagger.v3.oas.annotations.Operation;
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;
import net.javaguides.usermanagement.dto.UserDto;
import net.javaguides.usermanagement.service.UserService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@CrossOrigin("*")
@RestController
@RequestMapping("/api/users")
@Tag(name = "User Management", description = "APIs for managing users")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @Operation(summary = "Create a new user", description = "Add a new user to the system")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "User created successfully",
                    content = @Content(schema = @Schema(implementation = UserDto.class))),
            @ApiResponse(responseCode = "400", description = "Invalid request data",
                    content = @Content(schema = @Schema()))
    })
    @PostMapping
    public ResponseEntity<UserDto> createUser(@RequestBody UserDto userDto) {
        return ResponseEntity.ok(userService.createUser(userDto));
    }

    @Operation(summary = "Get user by ID", description = "Retrieve a user's details using their ID")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "User found",
                    content = @Content(schema = @Schema(implementation = UserDto.class))),
            @ApiResponse(responseCode = "404", description = "User not found",
                    content = @Content(schema = @Schema()))
    })
    @GetMapping("/{id}")
    public ResponseEntity<UserDto> getUserById(@PathVariable Long id) {
        return ResponseEntity.ok(userService.getUserById(id));
    }

    @Operation(summary = "Get all users", description = "Retrieve a list of all users in the system")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "Users retrieved successfully",
                    content = @Content(schema = @Schema(implementation = UserDto.class)))
    })
    @GetMapping
    public ResponseEntity<List<UserDto>> getAllUsers() {
        return ResponseEntity.ok(userService.getAllUsers());
    }

    @Operation(summary = "Update a user", description = "Update an existing user's details")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "User updated successfully",
                    content = @Content(schema = @Schema(implementation = UserDto.class))),
            @ApiResponse(responseCode = "404", description = "User not found",
                    content = @Content(schema = @Schema()))
    })
    @PutMapping("/{id}")
    public ResponseEntity<UserDto> updateUser(
            @PathVariable Long id,
            @RequestBody UserDto userDto) {
        return ResponseEntity.ok(userService.updateUser(id, userDto));
    }

    @Operation(summary = "Delete a user", description = "Delete a user from the system using their ID")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "204", description = "User deleted successfully"),
            @ApiResponse(responseCode = "404", description = "User not found",
                    content = @Content(schema = @Schema()))
    })
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
        return ResponseEntity.noContent().build();
    }
}

🚀 Step 4: Explanation of Swagger Annotations

✔️ @Tag(name = "User Management", description = "APIs for managing users")
➡️ Defines a category for API documentation.

✔️ @Operation(summary = "...", description = "...")
➡️ Describes the purpose of each API endpoint.

✔️ @ApiResponses(value = {...})
➡️ Lists possible HTTP responses with status codes.

✔️ @ApiResponse(responseCode = "200", description = "Success", content = @Content(...))
➡️ Specifies a response type for successful API calls.

✔️ @ApiResponse(responseCode = "404", description = "User not found")
➡️ Handles cases where resources are missing.

🚀 Step 5: Start the Spring Boot Application

📌 Run the application using:

mvn spring-boot:run

📌 Swagger UI will be available at:
👉 Swagger UI: http://localhost:8080/swagger-ui.html
👉 OpenAPI JSON: http://localhost:8080/v3/api-docs

🚀 Step 6: Testing APIs in Swagger UI

1️⃣ Open http://localhost:8080/swagger-ui.html in your browser.
2️⃣ You will see a list of API endpoints for UserController.
3️⃣ Click on any API endpoint (e.g., POST /api/users).
4️⃣ Click Try it out, enter sample data, and click Execute.
5️⃣ Observe the API response and status codes.

Generate REST API Documentation for Spring Boot Using Swagger

🎯 Summary: What We Achieved

✔️ Added Swagger to our Spring Boot project.
✔️ Annotated REST Controller with OpenAPI 3 annotations.
✔️ Generated interactive API documentation.
✔️ Tested APIs directly from Swagger UI.

🎉 Congratulations! You have successfully generated REST API documentation using Swagger! 🚀🔥

Comments

Spring Boot 3 Paid Course Published for Free
on my Java Guides YouTube Channel

Subscribe to my YouTube Channel (165K+ subscribers):
Java Guides Channel

Top 10 My Udemy Courses with Huge Discount:
Udemy Courses - Ramesh Fadatare