Create a pagination API with Spring Boot
Tags: springboot, pagination
Published: 2024-06-17 03:37:22

---
title: Create a pagination API with Spring Boot
published: true
date: 2024-06-14 09:12:00 UTC
tags: SpringBoot,Pagination
canonical_url: https://blog.stackpuz.com/create-a-pagination-api-with-spring-boot/
---

![Pagination API with Sping Boot](https://blog.stackpuz.com/media/posts/2/cover.jpg)

Splitting larger content into distinct pages is known as pagination. This method significantly enhances the user experience and speeds up the loading of web pages. This example will demonstrate how to create a pagination API using Spring-Boot and use MySQL as a database.

## Prerequisites 

- JAVA 17
- Maven
- MySQL

## Setup project 

Create a testing database named "example" and run the [database.sql](https://github.com/StackPuz/Example-Pagination-Spring-Boot-3/blob/main/database.sql) file to import the table and data.

## Project structure 

```
├─ pom.xml
└─ src
   └─ main
      ├─ java
      │  └─ com
      │     └─ stackpuz
      │        └─ example
      │           ├─ App.java
      │           ├─ controller
      │           │  └─ ProductController.java
      │           ├─ entity
      │           │  └─ Product.java
      │           └─ repository
      │              └─ ProductRepository.java
      └─ resources
         ├─ application.properties
         └─ static
            └─ index.html
```

## Project files 

### pom.xml 

This file contains the configuration and dependencies of the Maven project.

```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>
	<groupId>com.stackpuz</groupId>
	<artifactId>example-pagination</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>example-pagination</name>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.0.10</version>
	</parent>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
	        <groupId>org.springframework.boot</groupId>
	        <artifactId>spring-boot-devtools</artifactId>
	    </dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.30</version>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>
	   </dependencies>
</project>

```

### application.properties 

This file contains the database configuration.

```
spring.datasource.url = jdbc:mysql://localhost/example
spring.datasource.username = root
spring.datasource.password = 
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect
```

### App.java 

This file is the main entry point for the Spring Boot application.

```java
package com.stackpuz.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {
	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}
}
```

### ProductRepository.java 

This file defines the product repository by utilizing the PagingAndSortingRepository class, which has the pagination feature, so we can use it to implement the pagination with less effort.

```java
package com.stackpuz.example.repository;

import com.stackpuz.example.entity.Product;
import org.springframework.data.repository.PagingAndSortingRepository;

public interface ProductRepository extends PagingAndSortingRepository<Product, Integer> {
    
}
```

## Product.java 

This file defines the product entity that maps to our database table named "Product".

```java
package com.stackpuz.example.entity;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.math.BigDecimal;

@Entity
@Getter
@Setter
@NoArgsConstructor
public class Product {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;
    private String name;
    private BigDecimal price;
}
```

- We use the `lombok` library features to reduce the amount of code written for our entity by using `@Getter @Setter @NoArgsConstructor`

### ProductController.java 

This file is used to handle incoming requests and produce the paginated data for the client.

```java
package com.stackpuz.example.controller;

import java.util.Optional;
import com.stackpuz.example.entity.Product;
import com.stackpuz.example.repository.ProductRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
public class ProductController {

    @Autowired
    private ProductRepository repository;

    @GetMapping("/api/products")
    public List<Product> getProducts(@RequestParam("page") Optional<Integer> pageParam, @RequestParam("size") Optional<Integer> sizeParam, @RequestParam("order") Optional<String> orderParam, @RequestParam("direction") Optional<String> directionParam) {
        int page = pageParam.orElse(1) - 1;
        int size = sizeParam.orElse(10);
        String order = orderParam.orElse("id");
        String direction = directionParam.orElse("asc");
        return repository.findAll(PageRequest.of(page, size, Sort.by(Direction.fromString(direction), order))).getContent();
    }
}
```

- We use `@RequestParam` to map each query string to the URL.
- Because Spring Boot page index is starts at zero, so we use `pageParam.orElse(1) - 1` for this purpose.  
- `repository.findAll()` receives the `Pageable` object as the parameter. We create this `Pageable` object by using the `PageRequest.of()` method.
- `repository.findAll()` will return `Page<T>` object that contains all information about paginated data, but in this case we just want to return the product data, so we use `getContent()` here.  

### Index.html 

Instead of entering the URL manually to test our API, we used this file to create links for easier testing.

```html
<!DOCTYPE html>
<head>
</head>
<body>
    <ul>
        <li><a target="_blank" href="/api/products">Default</a></li>
        <li><a target="_blank" href="/api/products?page=2">Page 2</a></li>
        <li><a target="_blank" href="/api/products?page=2&size=25">Page 2 and Size 25</a></li>
        <li><a target="_blank" href="/api/products?page=2&size=25&order=name">Page 2 and Size 25 and Order by name</a></li>
        <li><a target="_blank" href="/api/products?page=2&size=25&order=name&direction=desc">Page 2 and Size 25 and Order by name descending</a></li>
    </ul>
</body>
</html>
```

## Run project 

```
mvn spring-boot:run
```

Open the web browser and goto http://localhost:8080

You will find this test page.

![test page](https://blog.stackpuz.com/media/posts/2/index-2.PNG)

## Testing 

### Testing without any parameters 

Click the "Default" link, and it will open the URL `http://localhost:8080/api/products`

![default test](https://blog.stackpuz.com/media/posts/2/default.PNG)

The API will return paginated data with default parameters (page = 1 and size = 10).

### Page index testing 

Click the "Page 2" link, and it will open the URL `http://localhost:8080/api/products?page=2`

![page index test](https://blog.stackpuz.com/media/posts/2/page-test.PNG)

The API will return paginated data on the second page, starting with product id 11

### Page size testing 

Click the "Page 2 and Size 25" link, and it will open the URL `http://localhost:8080/api/products?page=2&size=25`

![page size test](https://blog.stackpuz.com/media/posts/2/size-test.PNG)

The API will return paginated data on the second page by starting with product id 26 because the page size is 25.

### Order tesing 

Click the "Page 2 and Size 25 and Order by name" link, and it will open the URL `http://localhost:8080/api/products?page=2&size=25&order=name`

![order test](https://blog.stackpuz.com/media/posts/2/order-test.PNG)

The API will return paginated data on the second page, but the product order is based on the product name.

### Descending order testing 

Click the "Page 2 and Size 25 and Order by name descending" link, and it will open the URL `http://localhost:8080/api/products?page=2&size=25&order=name&direction=desc`

![descending order test](https://blog.stackpuz.com/media/posts/2/order-desc-test.PNG)

The API will return paginated data on the second page, but the product order is based on the product name in descending order.

## Conclusion 

In this article, you have learned how to utilize the PagingAndSortingRepository class to implement the pagination API for our web application with less effort. This will enhance the user experience and speed up your Spring Boot application. If you like this article please share it with your friends.

Source code: [https://github.com/stackpuz/Example-Pagination-Spring-Boot-3](https://github.com/stackpuz/Example-Pagination-Spring-Boot-3)

Create a CRUD Web App in Minutes: [https://stackpuz.com](https://stackpuz.com)