使用Prisma在Relay样式中实现分页
我在株式会社mofmof工作的shwld,第14天的Advent Calendar 2022,关于使用Next.js + 服务器端TypeScript + 函数风格创建干净的应用程序,我来解释一下实现意图。
昨天我写了关于GraphQL Resolver目录结构的内容
使用Prisma 在实现Relay Style 分页
在实施GraphQL分页时,有一种选择是采用Relay Style。这是由名为Relay的GraphQL客户端规定的规范,通过遵循该规范,可以轻松实现Relay Style的客户端分页。因此,我们选择了采纳这种方式。
我觉得自己实现可能会很困难,但是在graphql-relay中有一些方便的方法,所以实现起来相对容易。
可以使用以下的方法。
import { connectionFromArraySlice, cursorToOffset } from 'graphql-relay';
connectionFromArraySlice是一种方法,它可以通过传递切片数组的起始位置和数量来创建符合规范的连接。简单来说就是用于创建连接的。
顺便提一下,还有一个名为connectionFromArray的方法,它可以从未切片的长数组中通过起始位置和数量来提取相应的数组,并创建连接。
这次,我们将使用Prisma的connectionFromArraySlice来进行切片(从光标开始提取指定数量)操作。虽然听起来很难,但实际上很简单,可以按照以下步骤完成。
-
- 将接收到的游标(connection的after参数)转换为SQL的偏移量
-
- 将接收到的数量(connection的first参数)转换为SQL的限制数
-
- 使用Prisma的aggregate来获取数量
-
- 使用Prisma的findMany通过传递偏移量和限制数来获取结果
- 使用connectionFromArraySlice将结果和获取的数量转换为connection类型
我写着写着就意识到,在这篇文章中所讨论的内容中,并没有涉及到除了first和after之外的参数。
import { connectionFromArraySlice, cursorToOffset } from 'graphql-relay';
import type { ConnectionArguments } from 'graphql-relay';
args: ConnectionArguments
const take = args.first
const skip = cursorToOffset(args.after)
const accounts = await db.account.findMany({ skip, take })
const totalCount = await db.account.aggregate({ _count: true });
const relayConnection = connectionFromArraySlice(accounts, args, {
sliceStart: skip,
arrayLength: totalCount._count,
});
完成了。
参考代码:/用例/graphql解析器/src/共享/helpers/connection-helpers.ts
下次将会通知
明天我将写关于尝试使用Turborepo的文章。