Table of Contents#
- Prerequisites
- Understanding Default Swagger UI Order
- Methods to Reorder API Endpoints
- Step-by-Step Implementation
- Testing the Changes
- Troubleshooting Common Issues
- Conclusion
- 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:
- HTTP Method: Endpoints are grouped by HTTP methods (e.g.,
GET,POST,PUT) in alphabetical order. - 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:
@TagAnnotation: Groups endpoints into logical "tags" (e.g., "User Management") and assigns a priority to each tag (higher priority = appears first).@OperationAnnotation: Sets the position of individual endpoints within a tag (lowerpositionvalue = 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#
- Run your Spring Boot application.
- Navigate to Swagger UI at
http://localhost:8080/swagger-ui/index.html. - Verify the following:
- The "User Management" tag appears before "Product Management" (due to
priority = 1vs.2). - Within "User Management", endpoints are ordered as
POST(position 1),GET(2),PUT(3),DELETE(4).
- The "User Management" tag appears before "Product Management" (due to
Troubleshooting Common Issues#
1. Tags Not Sorted by Priority#
- Issue: Tags still appear in alphabetical order.
- Fix: Ensure the
tagsSorteris correctly configured in theOpenAPIbean. Verify thatTag::getPriorityis notnull(setpriorityin@Tagfor all controllers).
2. Methods Within a Tag Not Ordered#
- Issue: Methods are not ordered by
@Operation(position). - Fix:
- Ensure
positionvalues are unique within the tag (e.g., 1, 2, 3, not 1, 1, 2). - Use consecutive integers (gaps may cause unexpected ordering).
- Ensure
3. Springdoc Version Compatibility#
- Issue: Annotations like
@Tagor@Operationare 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).
- Spring Boot 3.x → Springdoc 2.x (e.g.,
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.