🏠Spring BootPaginating RESTful API responses in Spring MVC

Paginating RESTful API responses in Spring MVC

Pagination lets you split large RESTful API responses from Spring MVC into smaller chunks called pages. In this post, let us see how to use Spring MVC and Spring JPA to paginate a JSON response from a spring boot application.

Pagination and Sorting in Spring MVC

As we have seen earlier, we can implement pagination and sorting using spring data JPA. Spring MVC takes it to next level by injecting Pageable objects directly from the web layer.

Spring MVC allows you to pass the following optional query parameters to build a Pageable object on request scope. We can further use these Pageable objects in our JPA repository methods. So let’s see how to implement them.

Add Dependencies for Web and JPA

For this example, we are using Spring Data JPA and Spring Web components as dependencies.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>Code language: HTML, XML (xml)

Write a Pageable JPA repository method

Next, we need to write a repository that returns database records in pages. We have seen how to write and use them in detail in our previous post. In our case, we are using an Account class.

@Entity
public class Account {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Integer id;

    String accountNumber;
    String fullName;

    @JsonBackReference
    @ManyToOne
    Branch branch;

    BigDecimal balance;
    // getters and setters
}Code language: JavaScript (javascript)
public interface AccountRepository extends JpaRepository<Account, Integer> {

    @Query("select a from Account a")
    Page<Account> findAllAccounts(Pageable pageable);

}
Code language: PHP (php)

We will use this JPA pagination implementation in our service to pass the pageable from the Spring MVC controller.

Write a Spring MVC controller with Pageable parameter

Next, we can write an AccountService and AccountController that uses the AccountRepository interface.

@Service
public class AccountService {

    private final AccountRepository accountRepository;

    public AccountService(AccountRepository accountRepository) {
        this.accountRepository = accountRepository;
    }

    public Page<Account> getAccounts(Pageable pageable) {
        return accountRepository.findAllAccounts(pageable);
    }
}Code language: PHP (php)

Now the spring MVC controller class with pagination.

@RestController
public class AccountController {

    private final AccountService accountService;

    public AccountController(AccountService accountService) {
        this.accountService = accountService;
    }

    @GetMapping("/accounts")
    Page<Account> getAccounts(Pageable pageable) {
        return accountService.getAccounts(pageable);
    }
}Code language: PHP (php)

As you can see, the response itself is a Page object. Let’s run the application and see how this implementation behaves.

spring mvc pagination example using spring boot

As you see here, the response contains a content field that contains 20 of the account records. And it also comes with the current page-related metadata. From here, the clients can display total elements, number of pages, the current pages, etc in the front end.

But remember, we didn’t add any query parameters. But still, spring MVC uses pagination because, by default, spring sets the page size to 20 without any sorting.

Spring MVC pagination parameters

You can pass the following parameters to override the page behavior.

  1. page – Represents the Page number that you want to request (Starts at 0 and defaults to 0)
  2. size – Number of elements to return in the results ( Defaults to 20)
  3. sort – A list of strings that represent a fields to sort on. (including sort direction ASC, DESC)

So let’s check these parameters in action. To get view a specific page, you can do something like this.

http://localhost:8080/accounts?page=2Code language: JavaScript (javascript)

If you want to specify the number of elements on a page, then you can pass the size parameter

http://localhost:8080/accounts?page=2&size=15Code language: JavaScript (javascript)

If you decide to sort the objects by their fields, then you can pass a sort parameter with optional sort direction as well.

http://localhost:8080/accounts?page=2&size=15&sort=balance,DESCCode language: JavaScript (javascript)

You can even sort with two fields using multiple sort parameters.

http://localhost:8080/accounts?page=2&size=15&sort=balance,DESC&sort=id,ASCCode language: JavaScript (javascript)

Spring MVC Configurations for Pagination and sorting

Spring MVC offers certain configuration options to tweak the behavior of pagination. Here are important ones for you to know.

If your API already has a page or size parameter, then you can change the parameter names as shown below.

spring.data.web.pageable.page-parameter=chunk
spring.data.web.pageable.size-parameter=limit

You can also change the parameter names by adding a prefix to your pageable parameters.

spring.data.web.pageable.prefix=page

This way, the request should be something like /accounts?page_chunk=1&page_limit=30.

And if you prefer pages to start from 1 instead of 0, then you can use the following config.

spring.data.web.pageable.one-indexed-parameters=trueCode language: JavaScript (javascript)

Also, the size parameter can have a value up to 2000 by default. And the default page size is 20. Depending on your requirement, if you would like to increase or decrease it, then you should use the following configuration.

spring.data.web.pageable.default-page-size=30
spring.data.web.pageable.max-page-size=500Code language: PHP (php)

Summary

To sum it up, we learned how to implement pagination in RESTful web services using Spring MVC and Spring Data JPA. You can find the above example in our GitHub repository.

Related

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *