如何通过GitHub API在存储库上获取分支计数?

时间:2019-08-21 00:37:05

标签: github github-api

我是working on a UI,其中列出了给定用户或组织的所有存储库。这是一种树形格式,如果扩展,则第一级是存储库,第二级层次结构(子节点)将成为每个分支。

我使用的机制故意不要求我提取给定回购的所有分支的列表,因为API对API调用有速率限制。相反,我要做的就是指示它包含多少个子节点,而无需实际为其分配值(直到用户扩展它)。我几乎确定获取回购清单时会在结果中包括分支计数,但令我失望的是,我没有看到它。我只能看到叉子,观星者,观察者,问题等等的数量。除分支机构数量之外的所有事物。

UI的目的是,它会预先知道填充子节点的分支数量,但是直到用户展开父节点后才真正获取它们-因此立即显示<每个分支的strong>空占位符,然后异步加载要填充的实际分支。同样,由于我需要避免太多的API调用。当用户滚动时,它将使用分页来仅获取需要显示给用户的页面,并将其缓存以供以后显示。

具体来说,我使用的是Virtual TreeView for Delphi:

procedure TfrmMain.LstInitChildren(Sender: TBaseVirtualTree; Node: PVirtualNode;
  var ChildCount: Cardinal);
var
  L: Integer;
  R: TGitHubRepo;
begin
  L:= Lst.GetNodeLevel(Node);
  case L of
    0: begin
      //TODO: Return number of branches...
      R:= TGitHubRepo(Lst.GetNodeData(Node));
      ChildCount:= R.I['branch_count']; //TODO: There is no such thing!!!
    end;
    1: ChildCount:= 0; //Branches have no further child nodes
  end;
end;

我是否缺少某些东西,可以让我获得回购分支计数,而不必事先获取所有这些的完整列表?

1 个答案:

答案 0 :(得分:3)

您可以改用新的GraphQL API。这使您可以根据需要调整查询和结果。您可以在一个查询中完成这两个操作,而不是先获取计数然后再填充分支。

尝试Query Explorer

query {
  repository(owner: "octocat", name: "Hello-World") {
    refs(first: 100, refPrefix:"refs/heads/") {
      totalCount
      nodes {
        name
      }
    },
    pullRequests(states:[OPEN]) {
        totalCount
    }
  }
}
{
  "data": {
    "repository": {
      "refs": {
        "totalCount": 3,
        "nodes": [
          {
            "name": "master"
          },
          {
            "name": "octocat-patch-1"
          },
          {
            "name": "test"
          }
        ]
      },
      "pullRequests": {
        "totalCount": 192
      }
    }
  }
}

Pagination是使用游标完成的。首先,您获得第一页,一次最多100页,但是为了简洁起见,此处仅使用2页。响应将包含一个唯一的光标。

{
  repository(owner: "octocat", name: "Hello-World") {
    pullRequests(first:2, states: [OPEN]) {
      edges {
        node {
          title
        }
        cursor
      }
    }
  }
}
{
  "data": {
    "repository": {
      "pullRequests": {
        "edges": [
          {
            "node": {
              "title": "Update README"
            },
            "cursor": "Y3Vyc29yOnYyOpHOABRYHg=="
          },
          {
            "node": {
              "title": "Just a pull request test"
            },
            "cursor": "Y3Vyc29yOnYyOpHOABR2bQ=="
          }
        ]
      }
    }
  }
}

然后您可以在光标后要求更多元素。这将获得接下来的2个元素。

{
  repository(owner: "octocat", name: "Hello-World") {
    pullRequests(first:2, after: "Y3Vyc29yOnYyOpHOABR2bQ==", states: [OPEN]) {
      edges {
        node {
          title
        }
        cursor
      }
    }
  }
}

Queries can be written like functions and passed arguments。参数以单独的JSON格式发送。这样可以使查询成为简单的不变字符串。

此查询的作用与以前相同。

query NextPullRequestPage($pullRequestCursor:String) {
  repository(owner: "octocat", name: "Hello-World") {
    pullRequests(first:2, after: $pullRequestCursor, states: [OPEN]) {
      edges {
        node {
          title
        }
        cursor
      }
    }
  }
}

{
  "pullRequestCursor": "Y3Vyc29yOnYyOpHOABR2bQ=="
}

{ "pullRequestCursor": null }将获取第一页。


它的rate limit calculations比REST API更复杂。您可以每小时获得5000点积分,而不是每小时打电话。每个查询要花费一定数量的点,大致相当于Github计算结果要花费多少。您可以通过查询rateLimit信息来查询查询的费用。如果您将其传递给dryRun: true,它将仅告诉您费用,而无需运行查询。

{
  rateLimit(dryRun:true) {
    limit
    cost
    remaining
    resetAt
  }
  repository(owner: "octocat", name: "Hello-World") {
    refs(first: 100, refPrefix: "refs/heads/") {
      totalCount
      nodes {
        name
      }
    }
    pullRequests(states: [OPEN]) {
      totalCount
    }
  }
}
{
  "data": {
    "rateLimit": {
      "limit": 5000,
      "cost": 1,
      "remaining": 4979,
      "resetAt": "2019-08-21T05:13:56Z"
    }
  }
}

此查询仅花费一分。我还剩4979点,我将在世界标准时间05:13重新设置速率限制。

GraphQL API非常灵活。您应该能够使用更少的Github资源和更少的编程来处理更多操作,以解决速率限制。