为什么我在GitHub的GraphQL API中两次调用同一字段(具有不同的查询)时能够绕过分页

时间:2019-09-28 19:33:51

标签: github pagination graphql github-api

在尝试获取用户每个存储库的未解决问题数量时,我注意到了一些我不了解的内容。

当我使用以下查询时,要求我执行分页(按预期方式)-

query {
  user(login:"armsp"){
    repositories{
      nodes{
        name
        issues(states: OPEN){
          totalCount
        }
      }
    }    
  }
}

运行以上命令后的错误消息-

{
  "data": {
    "user": null
  },
  "errors": [
    {
      "type": "MISSING_PAGINATION_BOUNDARIES",
      "path": [
        "user",
        "repositories"
      ],
      "locations": [
        {
          "line": 54,
          "column": 5
        }
      ],
      "message": "You must provide a `first` or `last` value to properly paginate the `repositories` connection."
    }
  ]
}

但是,当我执行以下操作时,我实际上得到的所有结果对我来说都没有意义-

query {
  user(login:"armsp"){
    repositories{
      totalCount
    }
    repositories{
      nodes{
        name
        issues(states: OPEN){
          totalCount
        }
      }
    }   
  }
}

第二个查询中是否也不应要求我进行分页?

1 个答案:

答案 0 :(得分:1)

TLDR;这似乎是一个错误。在获取资源列表时,无法绕过应用的限制。

像这样限制响应是公共API的普遍功能-如果响应可能包含成千上万个结果,它将占用大量服务器资源来一次完成所有任务。允许用户进行此类查询既昂贵又有潜在的安全风险。

Github的意图似乎是总是限制获取资源列表时的结果数量。这在GraphQL方面没有得到很好的记录,但是与their REST API的行为相符:

  

默认情况下,返回多个项目的请求将被分页为30个项目。您可以使用?page参数指定其他页面。对于某些资源,您还可以使用?per_page参数将自定义页面大小设置为最大100。

对于连接,似乎仅在选择集中存在first字段时才运行lastnodes参数的检查。这是有道理的,因为这最终是我们要限制的字段-即使没有限制参数,请求totalDiskUsagetotalDiskUsage之类的其他字段也不会受到上述关注。

考虑how GraphQL handles selection sets with selections that have the same name时事情变得很时髦。无需深入了解细节,GraphQL将允许您多次请求相同的字段。如果所讨论的字段具有选择集,它将有效地将选择集合并为一个。所以

query {
  user(login:"armsp") {
    repositories {
      totalCount
    }
    repositories {
      totalDiskUsage
    }
  }
}

成为并等于

query {
  user(login:"armsp") {
    repositories {
      totalCount
      totalDiskUsage
    }
  }
}

旁注:如果您明确为一个字段指定别名,则上述 not 不成立,因为这两个字段具有不同的响应名称。

从技术上讲,这是所有要说的话:

query {
  user(login:"armsp"){
    repositories{
      totalCount
    }
    repositories{
      nodes{
        name
        issues(states: OPEN){
          totalCount
        }
      }
    }   
  }
}

也应该出现相同的MISSING_PAGINATION_BOUNDARIES错误。它并不意味着选择集合并的事实在某种程度上使现有的检查变得烦人。这显然是一个错误。但是,即使这看起来“可行”,它仍然无法解决Github在存储层上施加的任何限制-即使利用上述错误,您也始终会获得最多100个结果。