我是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;
我是否缺少某些东西,可以让我获得回购分支计数,而不必事先获取所有这些的完整列表?
答案 0 :(得分:3)
您可以改用新的GraphQL API。这使您可以根据需要调整查询和结果。您可以在一个查询中完成这两个操作,而不是先获取计数然后再填充分支。
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资源和更少的编程来处理更多操作,以解决速率限制。