Written by Gbolahan Olagunju✏️
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 for sample demonstrations.
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.
{ 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:
{
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:
//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.
In our example, we can decide to fetch 10 more records.
Here’s how it’ll look in code:
{
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.
LogRocket 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.
The post Pagination in GraphQL with Prisma the right way appeared first on LogRocket Blog.
Top comments (0)