echobind / bisonapp

A Full Stack Jamstack in-a-box brought to you by Echobind
MIT License
590 stars 28 forks source link

How to do Server-Side Pagination #129

Closed Kiho closed 3 years ago

Kiho commented 3 years ago

Is there any documentation like this? https://redwoodjs.com/cookbook/pagination

cball commented 3 years ago

Hey @Kiho, not yet. Though we certainly need them.

For now, your best bet is probably to look at the Nexus docs: https://nexusjs.org/docs/plugins/prisma/api#pagination

It's used like this:

objectType({
  name: 'User',
  definition(t) {
    t.model.posts({
      pagination: true,
    })
  },
})

queryType({
  definition(t) {
    t.crud.users({
      pagination: true,
    })
  },
})

There is also an example there of how you'd use in the client.

If the built-in Nexus pagination doesn't suit your needs, you can fallback writing it manually and using the pagination built into Prisma Client: https://www.prisma.io/docs/concepts/components/prisma-client/pagination.

Hope that helps!

Kiho commented 3 years ago

This is working for me.

// Queries
export const PostQueries = extendType({
  type: 'Query',
  definition(t) {
    // List Posts Query
    t.crud.post();
    t.crud.posts();

    t.field('postPage', {
      type: PostPage,
      args: {
        offset: intArg({ required: false }),
        limit: intArg({ required: false }),
      },
      resolve: async (_parent, args, ctx) => {
        const { offset, limit } = args;
        console.log(args);
        // if not provided, inform client/end-user
        if (!offset || !limit) throw new Error('Please provide an offset and limit.');

        let posts = [],
          count = 0;

        const take = limit || POSTS_PER_PAGE;
        const skip = (offset - 1) * take;

        try {
          count = await ctx.db.post.count();
          posts = await ctx.db.post.findMany({ skip, take });
        } catch (error) {
          console.log(error);
        }

        return { posts, count };
      },
    });
  },
});

export const PostPage = objectType({
  name: 'PostPage',
  definition(t) {
    t.list.field('posts', { type: 'Post' });

    t.int('count', {
      description: 'Count of total records',
    });
  },
});

However, it's a lot of boilerplate. is there any better way? I have lots of tables in my app. Sorry, I am new to graphql world. Thanks.