- An Accommodating Approach to Pagination
- Quick and Dirty Pagination
Let’s say you have an endpoint on your API that returns a list of objects, and it’s just no longer reasonable to expect it to return the entire list at once. It’s quite possibly time to introduce pagination. If you’ve never done this before it may sound a bit intimidating, but it doesn’t have to be. I’ve implemented endpoint pagination a couple of times. My first attempt was building some quick and dirty pagination, and although it got the job done it left me wanting to build a more robust solution. In this first post of the series, however, I’ll start by introducing you to the quick and dirty approach.
The request
The first thing you’ll need to do to support pagination is add a couple query parameters to the endpoint’s controller method.
[HttpGet("{customerId}")] public ActionResult<List<Invoice>> Get(Guid customerId, int page, int pageSize) { ... }
The pageSize
parameter allows the caller to specify how many objects are being requested. Imagine a book where each page has a list of objects of length pageSize
. The page
parameter would then specify which page of that book the caller is requesting.
The data layer
Implementing pagination in the repository is quite straightforward thanks to the Skip and Take methods provided by System.Linq
.
public List<Invoice> Get(Guid customerId, int page, int pageSize) { var offset = pageSize * (page - 1); return _dbContext.Invoices .Where(x => x.CustomerId == customerId) .Skip(offset) .Take(pageSize) .ToList(); }
The response
Now let’s update the controller method again. This time we’ll have it call the new repository method, and then return the results to the caller.
[HttpGet("{customerId}")] public ActionResult<List<Invoice>> Get(Guid customerId, int page, int pageSize) { return _invoiceRepository.Get(customerId, page, pageSize); }
And that’s it. Some quick and dirty pagination. Please stay tuned for the second post in this series, where I’ll demonstrate a better, far more accommodating approach.