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 客户端,一种解决方案就是完全放弃使用游标。您可以保留beforeafter 字段,但只需接受id(或_id 或任何PK)值而不是光标。这就是我最近在一个项目中所做的,它大大简化了事情。

【讨论】:

谢谢!我也在考虑这个问题,当我选择中继连接样式时,分页 ID 带来了一些复杂性,这在某些情况下(比如我的)可能是不必要的......

以上是关于GraphQL 分页 |第一个请求的主要内容,如果未能解决你的问题,请参考以下文章

Python GraphQL API 调用组合

在使用 graphql 缓存的基于游标的分页中跟踪页码

第1529期GraphQL入门指南

第 6 篇:分页接口

graphql,如何按第一个节点名称过滤?

ElasticSearch第5天 es实现分页查询的几种方式