Adding Pagination to the API
In this lesson, we're going to add pagination to our API
Adding pagination to the API#
Another important feature our API results should have is the pagination. This is basically showing a bigger result in smaller chunks β we usually divide the results in form of pages. Let me show you how we're going to implement it.
We're going to start with page 1 and set a fixed number of results to show on every page. So, we will need some data from the customer, like page index, and page size if they want to show it more than default. Our parameter list is getting bigger, so what we can do is create a new class which will have the properties we need. Inside Entity specifications, let's create a new class called CourseParams, and let's add the existing parameters first. We need Sort property of type string, we need CategoryId, which will be of type int and is optional. We need page index which will be an integer again. We will give a default value 1 to it so that when no page index value comes from the client, we show them the first page. We also want the page size, since our client can change the default page size; we can write the getter and setter. We will create a private field with an underscore and the value 3 for now. We will get this if no value is received; otherwise, we can use the value provided by the customer, or do we? I think we should limit the max number of results, so we create a new private const MaxPageSize and the value can be 20 for now although we have only 9 courses in our list. Now inside our setter, we will set our page size. If the value is more than MaxPageSize, we will return the MaxPageSize; otherwise, we will return the value.
Entity/Specification/CourseParams.cs
namespace Entity.Specifications
{
public class CourseParams
{
public string Sort { get; set; }
public int? CategoryId { get; set; }
public int PageIndex { get; set; } = 1;
private const int MaxPageSize = 20;
private int _pageSize = 3;
public int PageSize
{
get => _pageSize;
set => _pageSize = (value > MaxPageSize) ? MaxPageSize : value;
}
}
}
Let's go to our courses controller, and replace the parameters with CourseParams and name it the same. In this case, we need to tell our controller where we're expecting these parameters from; it can be the body, query or header. We are expecting from query, so we will simply write FromQuery before courseParams. Inside the specification, we can pass this as well. It will show us an error, so let's go in and fix that. We will replace the parameters with courseParams. We have to replace categoryId with courseParams.CategoryId and sort with courseParams.Sort.
[HttpGet]
public async Task<ActionResult<IReadOnlyList<CourseDto>>> GetCourses([FromQuery] CourseParams courseParams)
{
var spec = new CoursesWithCategoriesSpecification(courseParams);
var courses = await _repository.ListWithSpec(spec);
if (courses == null) return NotFound(new ApiResponse(404));
return Ok(_mapper.Map<IReadOnlyList<Course>, IReadOnlyList<CourseDto>>(courses));
}
Let's write our pagination now. We will go to the ISpecification class first. Here, we will write three more properties. We want two integers, Take and Skip, and a boolean property called IsPaging. Let's go to the BaseSpecification and implement it. Let's skip this not implemented exception with get and private set. Like the other methods in our BaseSpecification, we will create a new one for pagination; let's call it ApplyPagination. As parameters, it will accept take and skip, we will set them and set IsPaging to true.
Entity/Specifications/ISpecification.cs
This page is a preview of The newline Guide to Fullstack ASP.NET Core and React