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)
	}
}

注意事项

  1. 所有 GitHub 资源结构体对非重复字段使用指针值
  2. 大多数 API 方法都有可选参数
  3. 建议使用 context 包传递取消信号和截止时间
  4. 认证客户端不应在不同用户之间共享

更多示例代码可以参考 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))
}

最佳实践

  1. 认证方式

    • 个人访问令牌(PAT)适合脚本和自动化
    • OAuth适合需要用户授权的应用
    • GitHub App适合集成场景
  2. 错误处理

    _, 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)
    }
    
  3. 分页处理

    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
    }
    
  4. 速率限制处理

    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进行交互。根据你的具体需求选择合适的库和方法。

回到顶部