Pagination and Sorting in Spring Boot REST APIs

When your API deals with large datasets — like fetching thousands of users or records — loading everything at once is inefficient. That’s where pagination and sorting come in. They help limit the data sent to the client while giving control over how data is retrieved and displayed.

In this post, you’ll learn how to:

  • Add pagination and sorting in Spring Boot to a REST API
  • Use Spring Data’s Pageable and Sort
  • Customize response structure for frontend consumption
Pagination and Sorting in Spring Boot REST APIs

⚙️ Basic Setup

We’ll build a simple API to demonstrate paginated and sorted retrieval of User entities.

✅ Dependencies

Ensure you have Spring Data JPA and Web in your pom.xml:



  org.springframework.boot
  spring-boot-starter-web



  org.springframework.boot
  spring-boot-starter-data-jpa



  com.h2database
  h2
  runtime


📦 Entity & Repository

✅ User Entity


@Entity
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private String email;
    private int age;

    // Getters and setters
}

✅ User Repository


public interface UserRepository extends JpaRepository {
}

🔄 Implement Pagination & Sorting

Spring Data JPA automatically supports Pageable and Sort.

✅ Service Layer


@Service
public class UserService {
    private final UserRepository userRepository;
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    public Page getUsers(Pageable pageable) {
        return userRepository.findAll(pageable);
    }
}

🚀 REST Controller


@RestController
@RequestMapping("/api/users")
public class UserController {
    private final UserService userService;
    public UserController(UserService userService) {
        this.userService = userService;
    }
    @GetMapping
    public ResponseEntity> getUsers(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "5") int size,
            @RequestParam(defaultValue = "id,asc") String[] sort
    ) {
        // Extract sort parameters
        Sort.Direction direction = sort[1].equalsIgnoreCase("desc") ? Sort.Direction.DESC : Sort.Direction.ASC;
        Pageable pageable = PageRequest.of(page, size, Sort.by(direction, sort[0]));
        return ResponseEntity.ok(userService.getUsers(pageable));
    }
}

🔍 Test via Postman or Browser

Try the following URL:


GET http://localhost:8080/api/users?page=0&size=5&sort=name,asc

This retrieves the first page, with 5 users, sorted by name in ascending order.

🧾 Custom Page Response DTO (Optional)

Instead of returning Page directly, wrap it for better frontend readability:


public class UserPageResponse {
    private List content;
    private int pageNumber;
    private int pageSize;
    private long totalElements;
    private int totalPages;
    private boolean last;
}

And map it in controller:


UserPageResponse response = new UserPageResponse();
Page pageUsers = userService.getUsers(pageable);
response.setContent(pageUsers.getContent());
response.setPageNumber(pageUsers.getNumber());
response.setPageSize(pageUsers.getSize());
response.setTotalElements(pageUsers.getTotalElements());
response.setTotalPages(pageUsers.getTotalPages());
response.setLast(pageUsers.isLast());
return ResponseEntity.ok(response);

Sorting by Multiple Fields

Spring also supports multi-field sorting:


GET /api/users?sort=name,asc&sort=age,desc

In this case, modify the controller to handle multiple sort[] parameters:


Pageable pageable = PageRequest.of(page, size, Sort.by(
        Arrays.stream(sort)
              .map(order -> new Sort.Order(
                    order.split(",")[1].equalsIgnoreCase("desc") ? Sort.Direction.DESC : Sort.Direction.ASC,
                    order.split(",")[0]
              ))
              .collect(Collectors.toList())
));

🧠 Best Practices

PracticeDescription
✅ Validate page/size inputsAvoid invalid or excessive sizes
✅ Limit max page sizePrevent performance issues
✅ Default sortingFallback to id or createdAt
✅ Paginate large collectionsNever return entire datasets
✅ Use DTOs instead of EntitiesFor better control and flexibility

📌 Conclusion

Pagination and sorting in Spring Boot are essential features for building scalable REST APIs. With Spring Boot and Spring Data JPA, you can implement them with minimal configuration and maximum flexibility.

Use Pageable and Sort wisely to optimize both user experience and performance of your REST services.

References

Pagination and Sorting docs