GitHub API v4(GraphQL):如何使用分页遍历搜索结果?
利用GitHub API v4的
pageInfo实现分页遍历 没问题,我来给你详细拆解怎么用pageInfo完成分页遍历,这个逻辑其实很直观,咱们一步步来:
先搞懂pageInfo里的关键字段
hasNextPage:布尔值,直接告诉你是否还有下一页数据没拉取endCursor:当前页最后一个节点的游标标记,下一页查询需要用它来定位起始位置
分页遍历的具体步骤
1. 初始查询(第一页)
就是你现在用的这个查询,不需要加任何分页参数,它会返回第一页最多100条数据(因为你设置了first:100,这是GitHub API允许的最大单页数量),同时返回pageInfo。
2. 判断是否需要继续分页
检查返回结果里的search.pageInfo.hasNextPage:
- 如果是
true:说明还有更多数据,需要发起下一页查询 - 如果是
false:所有数据都拉取完毕,可以停止
3. 构造下一页查询
在search参数里添加after字段,值就是上一次查询返回的endCursor。比如你的第一次返回endCursor是Y3Vyc29yOjEwMA==,那下一页的查询应该是这样:
query { search(first: 100, type:USER, query:"location:usa repos:>0 language:java", after:"Y3Vyc29yOjEwMA==") { pageInfo { startCursor hasNextPage endCursor } userCount nodes { ... on User { bio company email id isBountyHunter isCampusExpert isDeveloperProgramMember isEmployee isHireable isSiteAdmin isViewer location login name url websiteUrl } } } }
4. 循环执行直到所有数据拉取完成
重复步骤2和3,每次用前一次返回的endCursor作为下一次查询的after参数,直到hasNextPage变成false。
代码示例(JavaScript)
这里给你一个实际可运行的示例,帮你理解循环逻辑(记得替换成你自己的GitHub访问令牌):
async function fetchAllMatchingUsers() { let hasNextPage = true; let endCursor = null; const allUsers = []; const githubToken = "YOUR_PERSONAL_ACCESS_TOKEN"; // 替换成你的令牌 while (hasNextPage) { // 动态构造查询,根据是否有endCursor添加after参数 const query = ` query { search( first: 100, type:USER, query:"location:usa repos:>0 language:java" ${endCursor ? `, after:"${endCursor}"` : ""} ) { pageInfo { hasNextPage endCursor } nodes { ... on User { bio company email id isBountyHunter isCampusExpert isDeveloperProgramMember isEmployee isHireable isSiteAdmin isViewer location login name url websiteUrl } } } } `; // 发送请求到GitHub GraphQL API const response = await fetch("https://api.github.com/graphql", { method: "POST", headers: { "Authorization": `Bearer ${githubToken}`, "Content-Type": "application/json" }, body: JSON.stringify({ query }) }); const data = await response.json(); const { search } = data.data; // 把当前页的用户添加到总列表 allUsers.push(...search.nodes); // 更新分页状态 hasNextPage = search.pageInfo.hasNextPage; endCursor = search.pageInfo.endCursor; // 处理速率限制:避免超过GitHub的API调用限制 const remainingRequests = response.headers.get("X-RateLimit-Remaining"); if (parseInt(remainingRequests) <= 10) { console.log("剩余请求次数不足,暂停1分钟"); await new Promise(resolve => setTimeout(resolve, 60000)); } } console.log(`共拉取到 ${allUsers.length} 个用户`); return allUsers; } // 调用函数开始拉取 fetchAllMatchingUsers();
注意事项
- 速率限制:GitHub GraphQL API对未认证请求限制很低,认证后每小时最多5000次请求,所以一定要用个人访问令牌,并且在代码里加入速率限制处理,避免被临时封禁。
- 单页最大数量:
first参数的最大值是100,所以每次分页最多只能拉取100条数据,没法设置更大的值。 - 令牌权限:你的个人访问令牌需要有
user相关的权限(比如read:user),否则可能无法获取完整的用户信息。
内容的提问来源于stack exchange,提问作者Furkan Yavuz
相关产品推荐
相关产品推荐

