GraphQL 分页 |第一个请求
Posted
技术标签:
【中文标题】GraphQL 分页 |第一个请求【英文标题】:GraphQL Pagination | The very first request 【发布时间】:2019-11-13 06:29:05 【问题描述】:根据使用graphQL进行分页的基于连接的模型,我有以下简化模式。
type User
id: ID!
name: String!
type UserConnection
totalCount: Int
pageInfo: PageInfo
edges: [UserEdge]
type UserEdge
cursor: String
node: User
type PageInfo
lastCursor: Int
hasNextPage: Boolean
type Query
users(first: Int, after: String): UserConnection
考虑 SPA 前端中的以下路由器:
/users
- 一旦用户点击此页面,我将从列表顶部获取前 10 条记录,并且我可以通过重用从第一个响应中检索到的游标来进一步分页.
/user/52
- 这里我想显示 10 条应该从 user52 的位置开始的记录。
问题在第一个请求中检索特定记录子集的可能方法是什么?在这一刻,我没有任何光标来构造类似的东西
query GetTenUsersAfter52
users(first: 10, after: "????") # struggling to pass anything as a cursor...
edges
node
name
我已经尝试过(一种可能的解决方案),我知道在后端,游标是数据库中记录的_id
的编码值。因此,在/users/52
上,我可以为该特定用户发出单独的请求,获取id
的值,然后在前端我可以计算一个游标并将其传递给上面查询中的后端。
但就我个人而言,我发现了几个缺点:
-
我将光标的计算方式暴露给前端,这很糟糕,因为如果我需要更改该过程,我需要在前端和后端进行更改...李>
我不想仅仅因为我需要将其 id 传递给
users
查询字段而为单个用户创建另一个查询字段。
我也不想为此进行 2 次 API 调用...
【问题讨论】:
您实际上是在使用 Relay 客户端,还是只是在架构中使用 Relay 约定并使用不同的客户端(例如 Apollo)? 我使用 Apollo Server 包作为 API 服务器和前端的 Apollo Client 以及 ReactJS。更重要的是,对我来说,要很好地掌握如何优雅地解决上述用例,这就是为什么我试图不提及除 graphQL 之外的任何特定技术。 【参考方案1】:这是中继式分页如何限制的一个很好的例子。您将遇到与创建突变类似的场景,手动将创建的对象添加到缓存中最终会搞砸您的分页,因为您将没有创建对象的光标。
只要您实际上不使用 Relay 客户端,一种解决方案就是完全放弃使用游标。您可以保留before
和after
字段,但只需接受id
(或_id
或任何PK)值而不是光标。这就是我最近在一个项目中所做的,它大大简化了事情。
【讨论】:
谢谢!我也在考虑这个问题,当我选择中继连接样式时,分页 ID 带来了一些复杂性,这在某些情况下(比如我的)可能是不必要的......以上是关于GraphQL 分页 |第一个请求的主要内容,如果未能解决你的问题,请参考以下文章