cyberangles blog

How to Change API Display Order in Swagger UI with Spring (Java): Reorder Controller Methods

Swagger UI is a popular tool for visualizing and interacting with RESTful APIs. It automatically generates a user-friendly interface from your API specifications, making it easier for developers to understand and test endpoints. However, by default, Swagger UI may not display your API endpoints in a logical or desired order. This can lead to confusion, especially when dealing with large APIs with multiple controllers and methods.

In this blog, we’ll explore how to reorder controller methods and groups in Swagger UI using Spring Boot and Springdoc OpenAPI (the modern successor to Springfox). We’ll cover step-by-step implementation, best practices, and troubleshooting tips to ensure your API documentation is organized and intuitive.

2026-01

Table of Contents#

  1. Prerequisites
  2. Understanding Default Swagger UI Order
  3. Methods to Reorder API Endpoints
  4. Step-by-Step Implementation
  5. Testing the Changes
  6. Troubleshooting Common Issues
  7. Conclusion
  8. References

Prerequisites#

Before starting, ensure you have the following:

  • A basic understanding of Spring Boot and REST APIs.
  • A Spring Boot project (2.x or 3.x). We’ll use Spring Boot 3.2 in this example.
  • Maven or Gradle for dependency management.
  • Springdoc OpenAPI (to integrate Swagger UI with Spring Boot).

Understanding Default Swagger UI Order#

By default, Swagger UI orders endpoints based on two criteria:

  1. HTTP Method: Endpoints are grouped by HTTP methods (e.g., GET, POST, PUT) in alphabetical order.
  2. Path: Within each HTTP method group, endpoints are sorted alphabetically by their URL path.

This default behavior often results in a disorganized display. For example, CRUD operations for a "User" resource might appear as DELETE, GET, POST, PUT (alphabetical by method), which is not intuitive. Instead, you might want them ordered as POST (create), GET (read), PUT (update), DELETE (delete).

To fix this, we need to:

  • Group endpoints logically (e.g., by controller or resource).
  • Order endpoints within groups (e.g., CRUD sequence).
  • Sort groups (if multiple) by importance.

Methods to Reorder API Endpoints#

The primary approach to reorder endpoints in Swagger UI with Springdoc OpenAPI involves:

  • @Tag Annotation: Groups endpoints into logical "tags" (e.g., "User Management") and assigns a priority to each tag (higher priority = appears first).
  • @Operation Annotation: Sets the position of individual endpoints within a tag (lower position value = appears first).
  • OpenAPI Configuration: Customizes Swagger UI to sort tags by their priority.

Step-by-Step Implementation#

Step 1: Set Up Spring Boot with Springdoc OpenAPI#

First, add Springdoc OpenAPI to your project. Springdoc is the recommended library for integrating OpenAPI (Swagger) with Spring Boot 2.x and 3.x.

For Maven (pom.xml):#

<dependencies>
    <!-- Spring Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
 
    <!-- Springdoc OpenAPI (Swagger UI) -->
    <dependency>
        <groupId>org.springdoc</groupId>
        <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
        <version>2.1.0</version> <!-- Use the latest version -->
    </dependency>
</dependencies>

For Gradle (build.gradle):#

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0' // Latest version
}

After adding the dependency, run your Spring Boot app. Swagger UI will be available at:
http://localhost:8080/swagger-ui/index.html

Step 2: Group Endpoints with @Tag#

Use the @Tag annotation to group endpoints into logical categories (e.g., "User Management", "Product Management"). This annotation can be applied at the controller level to group all endpoints in that controller under a single tag.

The @Tag annotation has a priority attribute (integer) to define the order of tags. Tags with higher priority values appear first in Swagger UI.

Example: Tagging a Controller#

import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
 
@RestController
@RequestMapping("/api/users")
@Tag(
    name = "User Management", // Name of the tag (displayed in Swagger UI)
    description = "CRUD operations for user management", // Optional description
    priority = 1 // Higher priority = appears first (e.g., 1 > 0)
)
public class UserController {
    // Endpoints will go here
}

If you have another controller (e.g., ProductController), assign it a lower priority to ensure it appears after "User Management":

@RestController
@RequestMapping("/api/products")
@Tag(name = "Product Management", description = "CRUD operations for products", priority = 2)
public class ProductController {
    // Endpoints...
}

Step 3: Order Methods Within a Group with @Operation#

Within a tag (group), use the @Operation annotation on individual methods to set their order. The position attribute in @Operation determines the sequence: lower values appear first.

Example: Ordering CRUD Methods#

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
 
@RestController
@RequestMapping("/api/users")
@Tag(name = "User Management", priority = 1)
public class UserController {
 
    // 1. Create (POST) - position 1 (first in group)
    @PostMapping
    @Operation(
        summary = "Create a new user",
        description = "Creates a new user with the provided details",
        position = 1 // Lower = first
    )
    public ResponseEntity<String> createUser(@RequestBody User user) {
        return ResponseEntity.ok("User created: " + user.getName());
    }
 
    // 2. Read (GET) - position 2 (second in group)
    @GetMapping("/{id}")
    @Operation(
        summary = "Get user by ID",
        description = "Retrieves a user by their unique ID",
        position = 2
    )
    public ResponseEntity<String> getUser(@PathVariable Long id) {
        return ResponseEntity.ok("User ID: " + id);
    }
 
    // 3. Update (PUT) - position 3 (third in group)
    @PutMapping("/{id}")
    @Operation(
        summary = "Update user",
        description = "Updates an existing user's details",
        position = 3
    )
    public ResponseEntity<String> updateUser(@PathVariable Long id, @RequestBody User user) {
        return ResponseEntity.ok("User updated: " + id);
    }
 
    // 4. Delete (DELETE) - position 4 (last in group)
    @DeleteMapping("/{id}")
    @Operation(
        summary = "Delete user",
        description = "Deletes a user by their ID",
        position = 4
    )
    public ResponseEntity<String> deleteUser(@PathVariable Long id) {
        return ResponseEntity.ok("User deleted: " + id);
    }
 
    // DTO for User (simplified)
    public record User(String name, String email) {}
}

Step 4: Sort Groups (Tags) by Priority#

By default, Swagger UI sorts tags alphabetically by name. To sort tags by their priority (set in @Tag), configure the OpenAPI bean to use a custom tagsSorter.

Create an OpenAPI Configuration Class#

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.tags.Tag;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
 
@Configuration
public class OpenApiConfig {
 
    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI()
            .info(new Info()
                .title("My API")
                .version("v1.0")
                .description("API documentation with ordered endpoints"))
            // Sort tags by priority (higher priority first)
            .tagsSorter(tags -> sortTagsByPriority(tags));
    }
 
    // Custom comparator to sort tags by priority (descending)
    private List<Tag> sortTagsByPriority(List<Tag> tags) {
        return tags.stream()
            .sorted(Comparator.comparingInt(Tag::getPriority).reversed()) // Higher priority first
            .collect(Collectors.toList());
    }
}

Here, tagsSorter takes the list of tags and sorts them by their priority in descending order (e.g., priority 1 > 2 > 0).

Testing the Changes#

  1. Run your Spring Boot application.
  2. Navigate to Swagger UI at http://localhost:8080/swagger-ui/index.html.
  3. Verify the following:
    • The "User Management" tag appears before "Product Management" (due to priority = 1 vs. 2).
    • Within "User Management", endpoints are ordered as POST (position 1), GET (2), PUT (3), DELETE (4).

Troubleshooting Common Issues#

1. Tags Not Sorted by Priority#

  • Issue: Tags still appear in alphabetical order.
  • Fix: Ensure the tagsSorter is correctly configured in the OpenAPI bean. Verify that Tag::getPriority is not null (set priority in @Tag for all controllers).

2. Methods Within a Tag Not Ordered#

  • Issue: Methods are not ordered by @Operation(position).
  • Fix:
    • Ensure position values are unique within the tag (e.g., 1, 2, 3, not 1, 1, 2).
    • Use consecutive integers (gaps may cause unexpected ordering).

3. Springdoc Version Compatibility#

  • Issue: Annotations like @Tag or @Operation are not recognized.
  • Fix: Use a Springdoc version compatible with your Spring Boot version:
    • Spring Boot 3.x → Springdoc 2.x (e.g., 2.1.0).
    • Spring Boot 2.x → Springdoc 1.x (e.g., 1.6.15).

Conclusion#

By using @Tag (to group and prioritize) and @Operation (to order within groups), combined with a custom tagsSorter, you can fully control the display order of endpoints in Swagger UI. This results in a more intuitive and user-friendly API documentation, making it easier for developers to understand and test your APIs.

References#