golang访问GitHub GraphQL API v4的插件库githubql的使用
Golang 访问 GitHub GraphQL API v4 的插件库 githubql 使用
简介
githubv4
是一个用于访问 GitHub GraphQL API v4 的客户端库。它提供了友好、简单且功能强大的 API,支持所有 GitHub GraphQL API v4 功能。
安装
go get github.com/shurcooL/githubv4
认证
GitHub GraphQL API v4 需要认证。推荐使用 golang.org/x/oauth2
包进行认证:
import "golang.org/x/oauth2"
func main() {
src := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: os.Getenv("GITHUB_TOKEN")},
)
httpClient := oauth2.NewClient(context.Background(), src)
client := githubv4.NewClient(httpClient)
// 使用 client...
}
如果是 GitHub Enterprise,使用 NewEnterpriseClient
:
client := githubv4.NewEnterpriseClient(os.Getenv("GITHUB_ENDPOINT"), httpClient)
// 使用 client...
简单查询
定义 Go 类型对应 GitHub GraphQL 模式,然后调用 client.Query
:
var query struct {
Viewer struct {
Login githubv4.String
CreatedAt githubv4.DateTime
}
}
err := client.Query(context.Background(), &query, nil)
if err != nil {
// 处理错误
}
fmt.Println(" Login:", query.Viewer.Login)
fmt.Println("CreatedAt:", query.Viewer.CreatedAt)
标量类型
GitHub GraphQL 标量类型对应 Go 类型:
var query struct {
Viewer struct {
Login githubv4.String
CreatedAt githubv4.DateTime
IsBountyHunter githubv4.Boolean
BioHTML githubv4.HTML
WebsiteURL githubv4.URI
}
}
也可以使用 Go 原生类型:
var query struct {
Viewer struct {
Login string // 如 "gopher"
CreatedAt time.Time // 如 time.Date(2017, 5, 26, 21, 17, 14, 0, time.UTC)
IsBountyHunter bool // 如 true
BioHTML string // 如 `I am learning <a href="https://graphql.org">GraphQL</a>!`
WebsiteURL string // 如 "https://golang.org"
}
}
参数和变量
使用 graphql
结构体标签定义参数:
var q struct {
Repository struct {
Description string
} `graphql:"repository(owner: \"octocat\", name: \"Hello-World\")"`
}
使用变量:
func fetchRepoDescription(ctx context.Context, owner, name string) (string, error) {
var q struct {
Repository struct {
Description string
} `graphql:"repository(owner: $owner, name: $name)"`
}
variables := map[string]interface{}{
"owner": githubv4.String(owner),
"name": githubv4.String(name),
}
err := client.Query(ctx, &q, variables)
return q.Repository.Description, err
}
内联片段
使用 graphql
标签定义内联片段:
var q struct {
RepositoryOwner struct {
Login string
Organization struct {
Description string
} `graphql:"... on Organization"`
User struct {
Bio string
} `graphql:"... on User"`
} `graphql:"repositoryOwner(login: \"github\")"`
}
分页
获取所有评论示例:
type comment struct {
Body string
Author struct {
Login string
AvatarURL string `graphql:"avatarUrl(size: 72)"`
}
ViewerCanReact bool
}
var q struct {
Repository struct {
Issue struct {
Comments struct {
Nodes []comment
PageInfo struct {
EndCursor githubv4.String
HasNextPage bool
}
} `graphql:"comments(first: 100, after: $commentsCursor)"` // 每页100条
} `graphql:"issue(number: $issueNumber)"`
} `graphql:"repository(owner: $repositoryOwner, name: $repositoryName)"`
}
variables := map[string]interface{}{
"repositoryOwner": githubv4.String(owner),
"repositoryName": githubv4.String(name),
"issueNumber": githubv4.Int(issue),
"commentsCursor": (*githubv4.String)(nil), // 获取第一页
}
// 获取所有页面的评论
var allComments []comment
for {
err := client.Query(ctx, &q, variables)
if err != nil {
return err
}
allComments = append(allComments, q.Repository.Issue.Comments.Nodes...)
if !q.Repository.Issue.Comments.PageInfo.HasNextPage {
break
}
variables["commentsCursor"] = githubv4.NewString(q.Repository.Issue.Comments.PageInfo.EndCursor)
}
变更
变更操作示例:
var m struct {
AddReaction struct {
Reaction struct {
Content githubv4.ReactionContent
}
Subject struct {
ID githubv4.ID
}
} `graphql:"addReaction(input: $input)"`
}
input := githubv4.AddReactionInput{
SubjectID: targetIssue.ID, // 从之前查询获取的目标issue ID
Content: githubv4.ReactionContentHooray,
}
err := client.Mutate(context.Background(), &m, input, nil)
if err != nil {
// 处理错误
}
fmt.Printf("Added a %v reaction to subject with ID %#v!\n", m.AddReaction.Reaction.Content, m.AddReaction.Subject.ID)
完整示例
以下是一个完整的示例,展示如何查询用户的登录名和创建时间:
package main
import (
"context"
"fmt"
"os"
"github.com/shurcooL/githubv4"
"golang.org/x/oauth2"
)
func main() {
// 认证
src := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: os.Getenv("GITHUB_TOKEN")},
)
httpClient := oauth2.NewClient(context.Background(), src)
client := githubv4.NewClient(httpClient)
// 定义查询
var query struct {
Viewer struct {
Login string
CreatedAt string
}
}
// 执行查询
err := client.Query(context.Background(), &query, nil)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
// 输出结果
fmt.Printf("Login: %s\n", query.Viewer.Login)
fmt.Printf("CreatedAt: %s\n", query.Viewer.CreatedAt)
}
这个示例展示了如何使用 githubv4 包进行基本的 GraphQL 查询。你可以根据需要扩展这个示例,添加更多字段或执行更复杂的查询和变更操作。
更多关于golang访问GitHub GraphQL API v4的插件库githubql的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang访问GitHub GraphQL API v4的插件库githubql的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用githubql访问GitHub GraphQL API v4
githubql是Go语言的一个第三方库,专门用于访问GitHub的GraphQL API v4版本。它提供了类型安全的GraphQL查询构建和执行功能。
安装
首先安装githubql库:
go get github.com/shurcooL/githubql
基本使用
1. 创建客户端
import (
"context"
"fmt"
"net/http"
"os"
"github.com/shurcooL/githubql"
"golang.org/x/oauth2"
)
func main() {
src := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: os.Getenv("GITHUB_TOKEN")},
)
httpClient := oauth2.NewClient(context.Background(), src)
client := githubql.NewClient(httpClient)
// 使用client进行查询...
}
2. 基本查询示例
type query struct {
Viewer struct {
Login githubql.String
CreatedAt githubql.DateTime
} `graphql:"viewer"`
}
func main() {
// ...创建client代码同上...
var q query
err := client.Query(context.Background(), &q, nil)
if err != nil {
// 处理错误
}
fmt.Println("Login:", q.Viewer.Login)
fmt.Println("Created at:", q.Viewer.CreatedAt)
}
3. 带参数的查询
type repositoryQuery struct {
Repository struct {
Description githubql.String
Stargazers struct {
TotalCount githubql.Int
}
} `graphql:"repository(owner: $owner, name: $name)"`
}
func main() {
// ...创建client代码同上...
var q repositoryQuery
variables := map[string]interface{}{
"owner": githubql.String("golang"),
"name": githubql.String("go"),
}
err := client.Query(context.Background(), &q, variables)
if err != nil {
// 处理错误
}
fmt.Println("Description:", q.Repository.Description)
fmt.Println("Stars:", q.Repository.Stargazers.TotalCount)
}
4. 分页查询
type issuesQuery struct {
Repository struct {
Issues struct {
Nodes []struct {
Title githubql.String
URL githubql.URI
}
PageInfo struct {
EndCursor githubql.String
HasNextPage githubql.Boolean
}
} `graphql:"issues(first: 10, after: $cursor)"`
} `graphql:"repository(owner: $owner, name: $name)"`
}
func main() {
// ...创建client代码同上...
var cursor *githubql.String
for {
var q issuesQuery
variables := map[string]interface{}{
"owner": githubql.String("golang"),
"name": githubql.String("go"),
"cursor": cursor,
}
err := client.Query(context.Background(), &q, variables)
if err != nil {
// 处理错误
}
for _, issue := range q.Repository.Issues.Nodes {
fmt.Println("Title:", issue.Title)
fmt.Println("URL:", issue.URL)
}
if !q.Repository.Issues.PageInfo.HasNextPage {
break
}
cursor = &q.Repository.Issues.PageInfo.EndCursor
}
}
高级用法
1. 使用Mutation
type addStarMutation struct {
AddStar struct {
Starrable struct {
Stargazers struct {
TotalCount githubql.Int
}
}
} `graphql:"addStar(input: $input)"`
}
func main() {
// ...创建client代码同上...
var m addStarMutation
input := githubql.AddStarInput{
StarrableID: "MDEwOlJlcG9zaXRvcnkxMjM0NTY3OA==", // 需要替换为实际的ID
}
variables := map[string]interface{}{
"input": input,
}
err := client.Mutate(context.Background(), &m, variables)
if err != nil {
// 处理错误
}
fmt.Println("Total stars:", m.AddStar.Starrable.Stargazers.TotalCount)
}
2. 使用内联片段(Inline Fragments)
type searchQuery struct {
Search struct {
Nodes []struct {
Typename string `graphql:"__typename"`
OnIssue struct {
Title githubql.String
} `graphql:"... on Issue"`
OnPullRequest struct {
Title githubql.String
} `graphql:"... on PullRequest"`
}
} `graphql:"search(query: $query, type: $type, first: 10)"`
}
func main() {
// ...创建client代码同上...
var q searchQuery
variables := map[string]interface{}{
"query": githubql.String("is:open"),
"type": githubql.SearchTypeIssue,
}
err := client.Query(context.Background(), &q, variables)
if err != nil {
// 处理错误
}
for _, node := range q.Search.Nodes {
switch node.Typename {
case "Issue":
fmt.Println("Issue:", node.OnIssue.Title)
case "PullRequest":
fmt.Println("PR:", node.OnPullRequest.Title)
}
}
}
注意事项
- 需要GitHub个人访问令牌(PAT),可以在GitHub开发者设置中创建
- 注意API速率限制
- 复杂的查询可能需要多次请求和分页处理
- 所有字段名必须与GraphQL schema中的完全匹配
- 使用
githubql
类型而不是Go原生类型
githubql库提供了类型安全的GraphQL查询方式,通过Go结构体标签定义查询结构,能够有效减少错误并提高开发效率。