Open toFrankie opened 9 months ago
前不久做 Github Blogger 插件开发时,遇到分页查询的场景,是用于查询 Issue 的。
使用 Github REST API 的话,可以很方便地分页查询,比如:
const {Octokit} = require('@octokit/core') const octokit = new Octokit({ auth: 'TOKEN', }) await octokit.request('GET /repos/{owner}/{repo}/issues', { owner: 'OWNER', repo: 'REPO', per_page: 20, page: 1, })
Related Link: List repository issues
由于它并没有提供 in:title 等更加复杂的搜索方式,只能用 GitHub GraphQL API 实现该需求。
in:title
我的需求是根据 title、label 来筛选 Issues,并支持分页查询。使用到的 API 是下面这个(Queries search):
title
label
借助 after、first、query 就能实现,比如:
after
first
query
query Issues { search( type: ISSUE query: "user:toFrankie repo:blog state:open label:2023" first: 5 after: null ) { issueCount pageInfo { startCursor endCursor hasNextPage hasPreviousPage } edges { node { ... on Issue { title } } } } }
如果对 Github Graph API 不熟的话,可以借助 Github 提供的 Explorer 进行验证,不懂可看 Using the Explorer。
其实从这里就看得出大概了,结果中的 pageInfo 结构如下
也就是说,如果已知 startCursor 和 endCursor 就能代入 Search 的 after 和 before 参数实现翻页的需求。
startCursor
endCursor
before
如果是按顺序从第一页、第二页......进行翻页的话,从本页的 pageInfo 中取出 endCursor 代入下一个查询的 after 中就行。如果我要从第 1 页调到第 5 页呢?
我试图去寻找 Cursor 的规律,从 Introduction to GraphQL 可知,Github 采用 GraphQL 的 cursor-based pagination 方式以实现翻页。
原来 Cursor 是用 Base64 编码后的字符串。
Y3Vyc29yOjU=
cursor:5
解码后可知是 cursor:offset 的形式,所以,实现跳页只要将其编码为 Base64 再传入 after 即可。如果是首页,可以不传入 after 参数或设为 null。
cursor:offset
null
其中 TOKEN、USER、REPO、LABEL 以及 query 等按需调整。
TOKEN
USER
REPO
LABEL
const {Octokit} = require('@octokit/core') const {encode} = require('js-base64') const octokit = new Octokit({ auth: 'TOKEN', }) const page = 2 const perPage = 5 const offset = (page - 1) * perPage const pageCursor = offset > 0 ? encode(`cursor:${offset}`) : null await octokit.graphql(` { search( type: ISSUE query: "user:USER repo:REPO state:open label:LABEL" first: ${perPage} after: ${pageCursor ? `"${pageCursor}"` : null} ) { issueCount pageInfo { startCursor endCursor hasNextPage hasPreviousPage } edges { node { ... on Issue { title } } } } } `)
RunKit Demo
背景
前不久做 Github Blogger 插件开发时,遇到分页查询的场景,是用于查询 Issue 的。
使用 Github REST API 的话,可以很方便地分页查询,比如:
由于它并没有提供
in:title
等更加复杂的搜索方式,只能用 GitHub GraphQL API 实现该需求。简介
我的需求是根据
title
、label
来筛选 Issues,并支持分页查询。使用到的 API 是下面这个(Queries search):借助
after
、first
、query
就能实现,比如:如果对 Github Graph API 不熟的话,可以借助 Github 提供的 Explorer 进行验证,不懂可看 Using the Explorer。
其实从这里就看得出大概了,结果中的 pageInfo 结构如下
也就是说,如果已知
startCursor
和endCursor
就能代入 Search 的after
和before
参数实现翻页的需求。如果是按顺序从第一页、第二页......进行翻页的话,从本页的 pageInfo 中取出
endCursor
代入下一个查询的after
中就行。如果我要从第 1 页调到第 5 页呢?我试图去寻找 Cursor 的规律,从 Introduction to GraphQL 可知,Github 采用 GraphQL 的 cursor-based pagination 方式以实现翻页。
原来 Cursor 是用 Base64 编码后的字符串。
解码后可知是
cursor:offset
的形式,所以,实现跳页只要将其编码为 Base64 再传入after
即可。如果是首页,可以不传入after
参数或设为null
。示例
其中
TOKEN
、USER
、REPO
、LABEL
以及query
等按需调整。References