Pagination in GraphQL with Prisma the right way
Tags: graphql
Published: 2020-01-19 21:23:29

---
title: Pagination in GraphQL with Prisma the right way
published: true
date: 2020-01-16 14:00:06 UTC
tags: graphql
canonical_url: https://blog.logrocket.com/pagination-in-graphql-with-prisma-the-right-way/
cover_image: https://thepracticaldev.s3.amazonaws.com/i/q6l3nngktf4nnrky38n2.png
---
**Written by [Gbolahan Olagunju](https://blog.logrocket.com/author/iamgbols/)**✏️

When working with a database that has millions of records, it’s very useful to adopt pagination since it helps us retrieve a subset of the data that we otherwise wouldn’t be able to access without querying every record on the table.

It can very expensive to retrieve this information from our database and it can have a huge impact on performance. It can also be expensive to render on the client side.

As of this writing, the default amount of records retrieved by Prisma on a table is 1,000 records — that is, if a subset of the record isn’t requested.

When querying a list of records, we can fetch certain parts (i.e. pages) of that list by supplying pagination arguments.

There are 5 major arguments we can use for pagination in Prisma: `first`, `last`, `after`, `before`, and `skip`.

In this article, we’ll be looking at various ways we can combine these arguments to effectively paginate our data.

We’ll also be using this [public API](https://graphiql.graphcms.com/simple/v1/swapi) for sample demonstrations.

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

### Using first or last with skip

Imagine an app that has pagination implemented with buttons as indicated below and has a page size of 10 items.

To get this to work, we would need to rewrite our `typedef` definition to accept arguments and also implement it in the resolver function for that query.

We won’t be doing that, seeing as how we are using an already-built public API. Looking at the documentation for this shows that the query has been defined to accept those arguments.

Okay, let’s get our feet wet.

- If we visit the public API, we’ll see the doc section.
- Clicking the doc section, we’ll see the query, mutation, and subscription.
- Then we’ll click on the query type to see all the queries that are available to us.

For the purposes of this article, we will be using the `allStarships` query.

```jsx
     { allStarships(first: 10) { id name length manufacturer } }
```

When we ran this code, a total of 10 records were returned. However, this isn’t complete for pagination because the same set of 10 records will be returned every time.

To ensure it works properly, we need to introduce another argument called `skip`.

Here’s how:

```jsx
{
    allStarships(first: 10, skip: 10) {
      id
      name
      length
      manufacturer
    }
  }
```

This gives us the second page, or the next 10 records. This can be done dynamically by sending the page number from the buttons multiplied by our page size.

We can get the first, second, and third page like this:

```jsx
//first page
 // number to skip pageNumber = 1
number = 10 * (1 - 1); // 0
...
allStarships(first: 10, skip: 0) 
//second page 
//number = 10 * (2 - 1); // 10
allStarships(first: 10, skip: 10) 
// third page 
//number = 10 * (2 - 1); // 10
allStarships(first: 10, skip: 20)
```

We could also use the last argument, but we would be querying the table (collection if mongoDB was the database of choice) from the last record entered rather than the above, which queries from the top of the table.

### Using before or after with skip

Imagine we have the navigation of a page implemented such that when you get to the bottom of the page, you can use the last `id` to fetch more records after it.


![load more posts](https://blog.logrocket.com/wp-content/uploads/2020/01/load-more-posts-nocdn-1.png)

In our example, we can decide to fetch 10 more records.

Here’s how it’ll look in code:

```jsx
{
    allStarships(first: 10, skip: 10) {
      id
      name
      length
      manufacturer
    }
  }
```

This gets us 10 records after the specified `id` . We can also use `last` with `before` to get records before the specified id.

**Note:** We can’t combine the use of `first` with `before`, or `last` with `after`.

If we do that in a query, the `first` or `last` is what will be applied (at either the end or the beginning of the list, depending on which is being used) while the `before` or `after` argument is simply ignored.

### Conclusion

It’s important to apply pagination when querying records from our database because it helps to optimize the performance of our servers. It also helps to curb expensive renders at the client level.

* * *
## 200's only ‎✅: Monitor failed and show GraphQL requests in production 

While GraphQL has some features for debugging requests and responses, making sure GraphQL reliably serves resources to your production app is where things get tougher. If you’re interested in ensuring network requests to the backend or third party services are successful, [try LogRocket.](https://www2.logrocket.com/signup-lr)

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/jd2amkhuiynfjf3i33qk.png)

[LogRocket](https://www2.logrocket.com/signup-lr) is like a DVR for web apps, recording literally everything that happens on your site. Instead of guessing why problems happen, you can aggregate and report on problematic GraphQL requests to quickly understand the root cause. In addition, you can track Apollo client state and inspect GraphQL queries' key-value pairs.

LogRocket instruments your app to record baseline performance timings such as page load time, time to first byte, slow network requests, and also logs Redux, NgRx, and Vuex actions/state. [Start monitoring for free.](https://www2.logrocket.com/signup-lr)
* * *

The post [Pagination in GraphQL with Prisma the right way](https://blog.logrocket.com/pagination-in-graphql-with-prisma-the-right-way/) appeared first on [LogRocket Blog](https://blog.logrocket.com).