golang访问GitHub REST API v3的插件库github
Golang 访问 GitHub REST API v3 的插件库 go-github
go-github 是一个用于访问 GitHub API v3 的 Go 客户端库。
安装
使用 Go 模块模式安装 go-github:
go get github.com/google/go-github/v74
或者直接在代码中导入:
import "github.com/google/go-github/v74/github" // 启用 Go 模块时
import "github.com/google/go-github/github" // 禁用 Go 模块时
使用示例
基本使用
package main
import (
"context"
"fmt"
"github.com/google/go-github/v74/github"
)
func main() {
// 创建 GitHub 客户端
client := github.NewClient(nil)
// 列出用户 "willnorris" 的所有组织
orgs, _, err := client.Organizations.List(context.Background(), "willnorris", nil)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
for _, org := range orgs {
fmt.Printf("Organization: %s\n", *org.Login)
}
}
带参数的请求
// 列出 GitHub 组织的公共仓库
opt := &github.RepositoryListByOrgOptions{Type: "public"}
repos, _, err := client.Repositories.ListByOrg(context.Background(), "github", opt)
认证
使用个人访问令牌进行认证:
client := github.NewClient(nil).WithAuthToken("your-access-token-here")
作为 GitHub App 认证
import (
"net/http"
"github.com/bradleyfalzon/ghinstallation/v2"
"github.com/google/go-github/v74/github"
)
func main() {
// 使用集成 ID 1 和安装 ID 99 创建传输层
itr, err := ghinstallation.NewKeyFromFile(http.DefaultTransport, 1, 99, "private-key.pem")
if err != nil {
// 处理错误
}
// 使用安装传输层创建客户端
client := github.NewClient(&http.Client{Transport: itr})
// 使用客户端...
}
处理速率限制
GitHub API 有速率限制,可以这样处理:
repos, _, err := client.Repositories.List(ctx, "", nil)
var rateErr *github.RateLimitError
if errors.As(err, &rateErr) {
log.Printf("达到速率限制,已使用 %d/%d\n", rateErr.Rate.Used, rateErr.Rate.Limit)
}
分页
处理分页请求的示例:
opt := &github.RepositoryListByOrgOptions{
ListOptions: github.ListOptions{PerPage: 10},
}
var allRepos []*github.Repository
for {
repos, resp, err := client.Repositories.ListByOrg(ctx, "github", opt)
if err != nil {
return err
}
allRepos = append(allRepos, repos...)
if resp.NextPage == 0 {
break
}
opt.Page = resp.NextPage
}
创建资源
创建资源时使用指针字段:
// 创建一个名为 "foo" 的私有仓库
repo := &github.Repository{
Name: github.String("foo"),
Private: github.Bool(true),
}
client.Repositories.Create(ctx, "", repo)
Webhooks 处理
处理 GitHub webhook 事件的示例:
func (s *GitHubEventMonitor) ServeHTTP(w http.ResponseWriter, r *http.Request) {
payload, err := github.ValidatePayload(r, s.webhookSecretKey)
if err != nil { /* 处理错误 */ }
event, err := github.ParseWebHook(github.WebHookType(r), payload)
if err != nil { /* 处理错误 */ }
switch event := event.(type) {
case *github.CommitCommentEvent:
processCommitCommentEvent(event)
case *github.CreateEvent:
processCreateEvent(event)
// 其他事件类型...
}
}
完整示例
这是一个完整的示例,展示如何获取用户仓库列表:
package main
import (
"context"
"fmt"
"os"
"github.com/google/go-github/v74/github"
"golang.org/x/oauth2"
)
func main() {
// 使用个人访问令牌创建认证客户端
ctx := context.Background()
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: os.Getenv("GITHUB_TOKEN")},
)
tc := oauth2.NewClient(ctx, ts)
client := github.NewClient(tc)
// 获取认证用户的所有仓库
repos, _, err := client.Repositories.List(ctx, "", &github.RepositoryListOptions{
Visibility: "private",
Affiliation: "owner",
ListOptions: github.ListOptions{PerPage: 100},
})
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Println("Your repositories:")
for _, repo := range repos {
fmt.Printf("- %s (%s)\n", *repo.Name, *repo.HTMLURL)
}
}
注意事项
- 所有 GitHub 资源结构体对非重复字段使用指针值
- 大多数 API 方法都有可选参数
- 建议使用 context 包传递取消信号和截止时间
- 认证客户端不应在不同用户之间共享
更多示例代码可以参考 go-github 的 example 目录。
更多关于golang访问GitHub REST API v3的插件库github的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang访问GitHub REST API v3的插件库github的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用Golang访问GitHub REST API v3
GitHub提供了完善的REST API v3接口,在Golang中有几个优秀的库可以帮助我们更方便地与GitHub API交互。下面我将介绍几个主流的Golang GitHub API库及其使用方法。
1. go-github官方库
GitHub官方维护的Golang客户端库是最权威的选择:
package main
import (
"context"
"fmt"
"log"
"github.com/google/go-github/v58/github"
"golang.org/x/oauth2"
)
func main() {
// 创建认证客户端
ctx := context.Background()
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: "your-github-access-token"},
)
tc := oauth2.NewClient(ctx, ts)
client := github.NewClient(tc)
// 获取用户信息
user, _, err := client.Users.Get(ctx, "")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Logged in as: %s\n", *user.Login)
// 创建仓库
repo := &github.Repository{
Name: github.String("my-new-repo"),
Private: github.Bool(false),
}
newRepo, _, err := client.Repositories.Create(ctx, "", repo)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Created repo: %s\n", *newRepo.HTMLURL)
}
2. shurcooL/githubv4
如果你需要使用GitHub GraphQL API v4,可以使用这个库:
package main
import (
"context"
"fmt"
"log"
"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 githubv4.String
CreatedAt githubv4.DateTime
}
}
err := client.Query(context.Background(), &query, nil)
if err != nil {
log.Fatal(err)
}
fmt.Println("Login:", query.Viewer.Login)
fmt.Println("Created at:", query.Viewer.CreatedAt)
}
3. 其他实用库
3.1 认证库
// 使用golang.org/x/oauth2进行OAuth认证
func getOAuthClient() *http.Client {
conf := &oauth2.Config{
ClientID: "your-client-id",
ClientSecret: "your-client-secret",
Scopes: []string{"repo", "user"},
Endpoint: github.Endpoint,
}
// 重定向用户到GitHub授权页面
url := conf.AuthCodeURL("state", oauth2.AccessTypeOnline)
fmt.Printf("Visit the URL for the auth dialog: %v", url)
// 使用授权码获取token
var code string
if _, err := fmt.Scan(&code); err != nil {
log.Fatal(err)
}
tok, err := conf.Exchange(context.Background(), code)
if err != nil {
log.Fatal(err)
}
return conf.Client(context.Background(), tok)
}
3.2 处理Webhooks
package main
import (
"fmt"
"log"
"net/http"
"github.com/go-playground/webhooks/v6/github"
)
func main() {
hook, _ := github.New(github.Options.Secret("your-github-webhook-secret"))
http.HandleFunc("/webhooks", func(w http.ResponseWriter, r *http.Request) {
payload, err := hook.Parse(r, github.PushEvent, github.PullRequestEvent)
if err != nil {
if err == github.ErrEventNotFound {
// 事件类型未处理
}
}
switch payload.(type) {
case github.PushPayload:
push := payload.(github.PushPayload)
fmt.Printf("%+v", push)
case github.PullRequestPayload:
pullRequest := payload.(github.PullRequestPayload)
fmt.Printf("%+v", pullRequest)
}
})
log.Fatal(http.ListenAndServe(":3000", nil))
}
最佳实践
-
认证方式:
- 个人访问令牌(PAT)适合脚本和自动化
- OAuth适合需要用户授权的应用
- GitHub App适合集成场景
-
错误处理:
_, resp, err := client.Repositories.Get(ctx, "owner", "repo") if err != nil { if ghErr, ok := err.(*github.ErrorResponse); ok { log.Printf("GitHub API error: %v", ghErr.Message) } log.Fatal(err) }
-
分页处理:
opt := &github.RepositoryListOptions{ ListOptions: github.ListOptions{PerPage: 50}, } var allRepos []*github.Repository for { repos, resp, err := client.Repositories.List(ctx, "", opt) if err != nil { log.Fatal(err) } allRepos = append(allRepos, repos...) if resp.NextPage == 0 { break } opt.Page = resp.NextPage }
-
速率限制处理:
rate, _, err := client.RateLimits(ctx) if err != nil { log.Fatal(err) } fmt.Printf("Rate limit: %d/%d (resets at %v)\n", rate.Core.Remaining, rate.Core.Limit, rate.Core.Reset)
这些库和示例代码应该能帮助你开始在Golang中与GitHub API进行交互。根据你的具体需求选择合适的库和方法。