Spring Boot Pagination & Sorting with REST API

In this topic, we will perform pagination and Sorting in the Spring Boot application with REST API. We will create an example of a Restful web service in Spring Boot with Spring Data JPA, Lombok and an H2 database. Spring Data JPA supports Paging and Sorting for this PagingAndSortingRepository interface of Spring Data provides methods that support Paging and Sorting functionality. These are the methods Iterable<T> findAll(Sort sort) and Page<T> findAll(Pageable pageable).
Table of content:
1. Keep eclipse IDE ready(STS integrated)
2. Create a Spring Boot Starter Project 
3. Maven Dependency
4. Define configuration in the application.properties file
5. Create an Entity class
6. Create a Repository
7. Create a Service
8. Insert Some Data in the H2 database through the SpringBootApplication class
9. Create a Controller
10. Run the app
11. Conclusion

1. Keep eclipse IDE ready(STS Integrated) 
Refer to this article How to Create Spring Project in IDE to create Spring Boot Project in Eclipse IDE.
2. Create a Spring Boot Starter Project 
 Add the following dependencies: 
• Spring Web
• Spring Data JPA
• H2 Database
• Lombok 

spring_boot_pagination_sorting_with_rest_api

3. Maven Dependency
pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.7.6</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.springjava</groupId>
	<artifactId>Spring_Boot_Pagination_Sorting_With_REST_API</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>Spring_Boot_Pagination_Sorting_With_REST_API</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
	</dependencies>

    <build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

4. Define configuration in the application.properties file

spring.datasource.url=jdbc:h2:mem:test
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=true

5. Create an Entity class
Employee.java:

package com.springjava.poc.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import lombok.Data;
@Entity
@Data
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String design;
}

→ This @Data annotation is Lombok annotation. It automatically generates setter and getter methods of fields of this Entity class at runtime.
6. Create a Repository
EmployeeRepository.java:

package com.springjava.poc.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.springjava.poc.entity.Employee;
public interface EmployeeRepository extends JpaRepository<Employee, Integer> {
}

→ JpaRepositorty<T, ID> is extending PagingAndSortingRepository<T, ID> interface. This PagingAndSortingRepository interface provides methods that support the Paging and Sorting feature.
→ This PagingAndSortingRepository is having two methods:
     • Iterable<T> findAll(Sort sort): Returns all entities sorted by the given options
    • Page<T> findAll(Pageable pageable): It returns a Page of entities meeting the paging restriction provided in the Pageable object.       

7. Create a Service
EmployeeService.java:

package com.springjava.poc.service;
import org.springframework.data.domain.Page;
import com.springjava.poc.entity.Employee;
public interface EmployeeService {
void save(Employee employee);
Page<Employee> getEmployeePagination(Integer pageNumber, Integer pageSize, String sort);
}

EmployeeServiceImpl.java:

package com.springjava.poc.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import com.springjava.poc.entity.Employee;
import com.springjava.poc.repository.EmployeeRepository;

@Service
public class EmployeeServiceImpl implements EmployeeService {
  @Autowired
  EmployeeRepository empRepo;

  @Override
  public void save(Employee employee) {
    empRepo.save(employee);
  }

  @Override
  public Page < Employee > getEmployeePagination(Integer pageNumber, Integer pageSize, String sort) {
    Pageable pageable = null;
    if (sort != null) {
      // with sorting
      pageable = PageRequest.of(pageNumber, pageSize, Sort.Direction.ASC, sort);
    } else {
      // without sorting
      pageable = PageRequest.of(pageNumber, pageSize);
    }
    return empRepo.findAll(pageable);
  }
}

→ Page<T> is an interface and sublist of a list of objects. This allows gain information about the position of it in the containing entire list. 
→ Pageable is an Abstract interface for pagination information.
→ PageRequest is a class which is an implementation of the Pageable interface.

8. Insert Some Data in the H2 database through the SpringBootApplication class

package com.springjava.poc;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import com.springjava.poc.entity.Employee;
import com.springjava.poc.service.EmployeeService;

@SpringBootApplication
public class SpringBootPaginationSortingWithRestApiApplication {

  public static void main(String[] args) {
    SpringApplication.run(SpringBootPaginationSortingWithRestApiApplication.class, args);
  }

  @Bean
  public CommandLineRunner demo(EmployeeService employeeService) {
    return (args) -> {
      // save few employee
      Employee emp1 = new Employee();
      emp1.setName("Adam");
      emp1.setDesign("Developer");

      Employee emp2 = new Employee();
      emp2.setName("Robert");
      emp2.setDesign("Tester");

      Employee emp3 = new Employee();
      emp3.setName("John");
      emp3.setDesign("Designer");

      Employee emp4 = new Employee();
      emp4.setName("William");
      emp4.setDesign("Server Admin");

      Employee emp5 = new Employee();
      emp5.setName("Robin");
      emp5.setDesign("Team Lead");

      Employee emp6 = new Employee();
      emp6.setName("Peter");
      emp6.setDesign("Developer");

      Employee emp7 = new Employee();
      emp7.setName("Jack");
      emp7.setDesign("Tester");

      Employee emp8 = new Employee();
      emp8.setName("Sam");
      emp8.setDesign("SEO Executive");

      Employee emp9 = new Employee();
      emp9.setName("Ronnie");
      emp9.setDesign("Developer");

      Employee emp10 = new Employee();
      emp10.setName("Ricky");
      emp10.setDesign("Project Lead");

      employeeService.save(emp1);
      employeeService.save(emp2);
      employeeService.save(emp3);
      employeeService.save(emp4);
      employeeService.save(emp5);
      employeeService.save(emp6);
      employeeService.save(emp7);
      employeeService.save(emp8);
      employeeService.save(emp9);
      employeeService.save(emp10);

    };
  }
}

9. Create a Controller
EmployeeController.java:

package com.springjava.poc.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.springjava.poc.entity.Employee;
import com.springjava.poc.service.EmployeeService;

@RestController
@RequestMapping("/api")
public class EmployeeController {
  @Autowired
  EmployeeService employeeService;

  @GetMapping("/employees/{pageNumber}/{pageSize}")
  public List < Employee > getEmployees(@PathVariable Integer pageNumber, @PathVariable Integer pageSize) {
    Page < Employee > data = employeeService.getEmployeePagination(pageNumber, pageSize, null);
    return data.getContent();
  }

  @GetMapping("/employees/{pageNumber}/{pageSize}/{sort}")
  public List < Employee > getEmployees(@PathVariable Integer pageNumber, @PathVariable Integer pageSize, @PathVariable String sort) {
    Page < Employee > data = employeeService.getEmployeePagination(pageNumber, pageSize, sort);
    return data.getContent();
  }
}

10. Run the app
Right-click on the SpringBootApplication class and then click on the Run As after then click on the Java Application.
Running the Application:
H2 Database Console: Hitting this URL http://localhost:8080/h2-console on the browser for H2 Database.

spring_boot_pagination_sorting_with_rest_api

Then click on the Connect button to connect the database and a check table is created and the data is inserted or not.

spring_boot_pagination_sorting_with_rest_api

Test the endpoint in the Postman tool:

Hitting this URL: http://localhost:8080/api/employees/0/5

spring_boot_pagination_sorting_with_rest_api

Hitting this URL: http://localhost:8080/api/employees/0/5/name

spring_boot_pagination_sorting_with_rest_api

11. Conclusion
In this topic, we learnt how to implement the Pagination and  Sorting functionality in Spring Boot Application with REST API using Spring Data JPA.

Leave a Comment