Server-side Pagination
Published: 2023-12-04 02:27:47

## Pagination Feature
I've been trying to work more on implementing back-end functionalities. When I was searching Github to find an issue related to back-end functionality, I came across this [issue](https://github.com/markjamesm/Sprocket/issues/5) that grabbed my attention. The issue was about implementing pagination for 2 api endpoints. Pagination is the functionality to divide up and organize the data in separate sequential pages. I was interested in working on this issue because my only experience implementing a pagination feature was done on the front-end side of a web application.

## The Process
### Setup
The setup to work on this project was straightforward. I forked and cloned the project. Then, I had to update my .NET SDK from version 6 to 7, and to update my Visual Studio 2022 to be able to build and run the application.

### Changes
My main concern when implementing the pagination feature was to choose the right strategy with the most flexibility for future changes. I chose to add my implementation to the ListPosts() function for the GET posts api and the ListPages() for the GET pages api. I added 2 int parameters to each of these functions that handled the number of items for each page and the number of pages. The parameters allow for flexibility on how many items can be included for each page but they also had default values. Then I used Arithmetic calculations, Skip() and Take() functions, based on the provided values in the parameters to check which items to include and skip from the retrieved data, mapped the data and returned the results. The implementation for both functions can be found below:
```C#
public async Task<ActionResult<PagesDto>> ListPages(int pageNum = 1, int pageSize = 10)
    {
        int skipItem = (pageNum - 1) * pageSize;

        var pagesFromDb = await _dbContext.Pages.Skip(skipItem).Take(pageSize).ToListAsync();
        
        var pagesDto = new PagesDto();
        
        foreach (var page in pagesFromDb)
        {
            var pageDto = new PageDto
            {
                Id = page.Id,
                Author = page.Author,
                Body = page.Body,
                Title = page.Title
            };
            
            pagesDto.Pages.Add(pageDto);
        }
        
        return pagesDto;
    }

public async Task<ActionResult<PostsDto>> ListPosts(int postNumber = 1, int postSize = 10)
    {
        int skipItem = (postNumber - 1) * postSize;

        var postsFromDb = await _dbContext.Posts.Skip(skipItem).Take(postSize).ToListAsync();
        
        var postsDto = new PostsDto();
        
        foreach (var post in postsFromDb)
        {
            var postDto = new PostDto
            {
                Id = post.Id,
                Author = post.Author,
                Body = post.Body,
                Title = post.Title
            };
            
            postsDto.Posts.Add(postDto);
        }
        
        return postsDto;
    }
```
After I made my changes, I committed them, and made a [PR](https://github.com/markjamesm/Sprocket/pull/6) to be reviewed.
## What I learned
Even though I had experience with implementing pagination functionality before, it was still interesting to implement the same concept I had used on front-end but for the back-end this time. I think that if I want to implement a pagination functionality in the future, I will take the best of both worlds, and have a mixed implementation between the back-end and the front-end, because I believe it will offer the most flexibility. But, choosing an implementation strategy should be fluid and dependent on what is needed for the overall goal of the program.