I'm trying to add cursor-based pagination to a table of posts using a Next.js API Route, Prisma and useSWRInfinite.
Currently, I'm using Prisma with a Next.js API Route to fetch the ten most recent posts for a site with useSWR, sorted by createdAt in descending order.
I'd like to use the useSWRInfinite hook to access the API endpoint and display a 'Load More' button to load a further ten posts using cursor-based pagination, in addition to displaying a count of the total number of posts.
As I understand from the SWR and Prisma docs, the API route will need to be modified to accept a cursor and return the next cursor. The useSWRInfinite hook also needs some logic to send/receive the current/next cursor.
Here is the code:
API Route
export async function getPost(
req: NextApiRequest,
res: NextApiResponse,
session: Session
): Promise<void | NextApiResponse<AllPosts | (WithSitePost | null)>> {
const { postId, siteId, published } = req.query;
if (
Array.isArray(postId) ||
Array.isArray(siteId) ||
Array.isArray(published)
)
return res.status(400).end("Bad request. Query parameters are not valid.");
if (!session.user.id)
return res.status(500).end("Server failed to get session user ID");
try {
if (postId) {
const post = await prisma.post.findFirst({
...
});
return res.status(200).json(post);
}
const site = await prisma.site.findFirst({
where: {
id: siteId,
user: {
id: session.user.id,
},
},
});
const posts = !site
? []
: await prisma.post.findMany({
take: 10,
where: {
site: {
id: siteId,
},
published: JSON.parse(published || "true"),
},
orderBy: {
createdAt: "desc",
},
});
return res.status(200).json({
posts,
site,
});
} catch (error) {
console.error(error);
return res.status(500).end(error);
}
}
Posts Page
const router = useRouter();
const { id: siteId } = router.query;
const { data } = useSWR<SitePostData>(
siteId && `/api/post?siteId=${siteId}&published=true`,
fetcher,
{
onSuccess: (data) => !data?.site && router.push("/"),
}
);
CodePudding user response:
Take a look at Prisma's documentation on cursor-based pagination: https://www.prisma.io/docs/concepts/components/prisma-client/pagination#cursor-based-pagination
You can provide a skip
property to skip X elements in your findMany
query, and/or a cursor
property to tell Prisma where to start the find from. You will need both: skip: 1
to skip the cursor, and cursor
to indicate the ID of the property from which the find should begin.