Project Icon

githubv4

Go语言实现的GitHub GraphQL API v4客户端库

githubv4是一个Go语言编写的GitHub GraphQL API v4客户端库。该库提供简洁易用的API接口,支持查询、变量、内联片段和分页等功能,可通过代码生成覆盖全部GitHub GraphQL API。它注重性能和正确性,能帮助开发者高效地与GitHub API交互。

githubv4

Go 参考

githubv4 包是用于访问 GitHub GraphQL API v4 (https://docs.github.com/en/graphql) 的客户端库。

如果你正在寻找 GitHub REST API v3 的客户端库,推荐使用 github 包(也称为 go-github)。

重点

  • 友好、简单且功能强大的 API。
  • 正确性、高性能和高效率。
  • 通过从 schema 生成代码来支持 GitHub GraphQL API v4 的所有功能。

安装

go get github.com/shurcooL/githubv4

使用方法

身份验证

GitHub GraphQL API v4 需要身份验证githubv4 包不直接处理身份验证。相反,在创建新客户端时,你需要传入一个执行身份验证的 http.Client。最简单且推荐的方法是使用 golang.org/x/oauth2 包。你需要从 GitHub 获取一个 OAuth 令牌(例如,个人访问令牌)并具有正确的权限范围。然后:

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,请使用 githubv4.NewEnterpriseClient

client := githubv4.NewEnterpriseClient(os.Getenv("GITHUB_ENDPOINT"), httpClient)
// 使用 client...

简单查询

要进行查询,你需要定义一个与 GitHub GraphQL schema 相对应的 Go 类型,并包含你想要查询的字段。你可以在 https://docs.github.com/en/graphql/reference/queries 查看 GitHub GraphQL schema。

例如,要进行以下 GraphQL 查询:

query {
	viewer {
		login
		createdAt
	}
}

你可以定义这个变量:

var query struct {
	Viewer struct {
		Login     githubv4.String
		CreatedAt githubv4.DateTime
	}
}

然后调用 client.Query,传入一个指向它的指针:

err := client.Query(context.Background(), &query, nil)
if err != nil {
	// 处理错误
}
fmt.Println("    Login:", query.Viewer.Login)
fmt.Println("CreatedAt:", query.Viewer.CreatedAt)

// 输出:
//     Login: gopher
// CreatedAt: 2017-05-26 21:17:14 +0000 UTC

标量类型

对于 https://docs.github.com/en/graphql/reference/scalars 列出的 GitHub GraphQL schema 中的每个标量,githubv4 包中都有对应的 Go 类型。

你可以在编写查询时使用这些类型:

var query struct {
	Viewer struct {
		Login          githubv4.String
		CreatedAt      githubv4.DateTime
		IsBountyHunter githubv4.Boolean
		BioHTML        githubv4.HTML
		WebsiteURL     githubv4.URI
	}
}
// 调用 client.Query() 并在 query 中使用结果...

然而,根据你计划如何使用查询结果,使用其他 Go 类型通常会更方便。

encoding/json 规则用于将 GraphQL 响应中的单个 JSON 编码字段转换为 Go 值。详情请参阅 https://godoc.org/encoding/json#Unmarshal。会遵循 json.Unmarshaler 接口。

这意味着你可以通过使用预声明的 Go 类型来简化前面的查询:

// import "time"

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"。
	}
}
// 调用 client.Query() 并在 query 中使用结果...

DateTime 标量被描述为"ISO-8601 编码的 UTC 日期字符串"。如果你想以该形式获取而不解析为 time.Time,可以使用 string 类型。例如,这样可以工作:

// import "html/template"

type MyBoolean bool

var query struct {
	Viewer struct {
		Login          string        // 例如,"gopher"。
		CreatedAt      string        // 例如,"2017-05-26T21:17:14Z"。
		IsBountyHunter MyBoolean     // 例如,MyBoolean(true)。
		BioHTML        template.HTML // 例如,template.HTML(`I am learning <a href="https://graphql.org">GraphQL</a>!`)。
		WebsiteURL     template.URL  // 例如,template.URL("https://golang.org")。
	}
}
// 调用 client.Query() 并在 query 中使用结果...

参数和变量

通常,你会想要在某些字段上指定参数。你可以使用 graphql 结构体字段标签来实现这一点。

例如,要进行以下 GraphQL 查询:

{
	repository(owner: "octocat", name: "Hello-World") {
		description
	}
}

你可以定义这个变量:

var q struct {
	Repository struct {
		Description string
	} `graphql:"repository(owner: \"octocat\", name: \"Hello-World\")"`
}

然后调用 client.Query

err := client.Query(context.Background(), &q, nil)
if err != nil {
	// 处理错误
}
fmt.Println(q.Repository.Description)

// 输出:
// My first repository on GitHub!

然而,这只适用于参数是常量且预先已知的情况。否则,你需要使用变量。将结构体字段标签中的常量替换为变量名:

// fetchRepoDescription 获取指定所有者和名称的仓库描述。
func fetchRepoDescription(ctx context.Context, owner, name string) (string, error) {
	var q struct {
		Repository struct {
			Description string
		} `graphql:"repository(owner: $owner, name: $name)"`
	}

在向 GraphQL 发送变量时,你需要使用与 GraphQL 标量类型完全匹配的类型,否则 GraphQL 服务器将返回错误。

因此,定义一个 variables 映射,其中包含转换为 GraphQL 标量类型的值:

	variables := map[string]interface{}{
		"owner": githubv4.String(owner),
		"name":  githubv4.String(name),
	}

最后,调用 client.Query 并提供 variables

	err := client.Query(ctx, &q, variables)
	return q.Repository.Description, err
}

内联片段

一些 GraphQL 查询包含内联片段。你可以使用 graphql 结构体字段标签来表示它们。

例如,要进行以下 GraphQL 查询:

{
	repositoryOwner(login: "github") {
		login
		... on Organization {
			description
		}
		... on User {
			bio
		}
	}
}

你可以定义这个变量:

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 (
	OrganizationFragment struct {
		Description string
	}
	UserFragment struct {
		Bio string
	}
)

var q struct {
	RepositoryOwner struct {
		Login                string
		OrganizationFragment `graphql:"... on Organization"`
		UserFragment         `graphql:"... on User"`
	} `graphql:"repositoryOwner(login: \"github\")"`
}

然后调用 client.Query

err := client.Query(context.Background(), &q, nil)
if err != nil {
	// 处理错误
}
fmt.Println(q.RepositoryOwner.Login)
fmt.Println(q.RepositoryOwner.Description)
fmt.Println(q.RepositoryOwner.Bio)

// 输出:
// github
// How people build software.
//

分页

假设你想获取一个问题的完整评论列表,而不仅仅是前10条左右。要做到这一点,你需要执行多个查询并使用分页信息。例如:

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), // 获取第一页时使用空指针作为after参数。
}

// 获取所有页面的评论。
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)
}

执行分页有多种方式。可以考虑使用PageInfo对象中的其他字段。

突变操作

突变操作通常需要先执行查询来获取信息。假设你已经完成了这一步。

例如,要执行以下GraphQL突变:

mutation($input: AddReactionInput!) {
	addReaction(input: $input) {
		reaction {
			content
		}
		subject {
			id
		}
	}
}
variables {
	"input": {
		"subjectId": "MDU6SXNzdWUyMTc5NTQ0OTc=",
		"content": "HOORAY"
	}
}

你可以定义:

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, // 来自之前查询的目标问题的ID。
	Content:   githubv4.ReactionContentHooray,
}

然后调用client.Mutate

err := client.Mutate(context.Background(), &m, input, nil)
if err != nil {
	// 处理错误。
}
fmt.Printf("为ID为%#v的主题添加了一个%v反应!\n", m.AddReaction.Subject.ID, m.AddReaction.Reaction.Content)

// 输出:
// 为ID为"MDU6SXNzdWUyMTc5NTQ0OTc="的主题添加了一个HOORAY反应!

目录

路径概要
example/githubv4devgithubv4dev是一个当前用于开发githubv4包的测试程序。

许可证

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号