How to paginate a Prisma Graphql query with typescript
TLDR; Add the meta data in the resolver and add a new type in graphql to return the meta data.
I shamelessly am taking this from a post on Prisma's old forum here. I'm going to go over it in a little more detail and since I use typescript my examples will be in typescript.
Things to do:
- Add two new types to our graphql type definitions
- Update the query graphql type definition
- Update the resolver
New Type Defs
For this example I'll use posts as the data we're returning.
type Post {
id: String!
slug: String!
text: String!
isPublished: Boolean!
}
type PaginatedPosts {
nodes: [Post!]!
meta: PaginatedPostsMeta!
}
type PaginatedPostsMeta {
nodeCount: Int!
pageCount: Int!
pageCurrent: Int!
nodesPerPage: Int!
}
You can see we add some types to wrap around our normal response of an array of posts.
Update query
We need to update the query definition to return the new model we just added.
posts(page: Int!): PaginatedPosts!
Update Resolver
import { Prisma } from "../prisma/generated/prisma-client"
interface PostsArgs {
page: number
}
interface Context {
db: Prisma
}
function posts(parent, args: PostsArgs, ctx: Context) {
const { page } = args
const PAGE_SIZE = 10
const = {where: { isPublished: true }}
return {
nodes: ctx.db.posts({
...where,
orderBy: "createdAt_DESC",
first: PAGE_SIZE,
skip: page * PAGE_SIZE,
}),
meta: async () => {
const count = await ctx.db.templatesConnection(where).aggregate().count()
return {
nodeCount: count,
pageCount: Math.ceil(count / PAGE_SIZE),
pageCurrent: (page * PAGE_SIZE) / PAGE_SIZE,
nodesPerPage: PAGE_SIZE,
}
}
}
}