使用 Golang 开发 Github GraphQL API

Qiang 发布在技术 1

概述

GraphQL 是一种用于 API 的查询语言,它由 Facebook 开发并于 2015 年发布。相比于传统的 RESTful API,GraphQL 更加灵活、高效、易于扩展和维护。它允许客户端明确指定需要从服务器获取的数据,并且能够在一个请求中一次性获取多个资源的数据。这也是 GraphQL 的最大优势之一。

GitHub GraphQL API 是 GitHub 平台提供的一种 API 服务,可以使用 GraphQL 查询和修改 GitHub 上的资源。它允许开发者使用GraphQL 查询 GitHub 上的组织、存储库、问题、拉取请求等各种信息,也可以用于创建或更新 GitHub 资源。相比于 RESTful API,GitHub GraphQL API 更加灵活,能够在一个请求中获取更多的数据,从而减少网络请求的次数。同时,由于 GraphQL 使用强类型系统,因此可以在客户端对查询进行类型检查,减少了数据转换的错误。

创建 Github GraphQL API Token

要使用 Github GraphQL API,您需要首先创建自己的 Github Token。步骤如下:

  1. 登录到您的 Github 帐户。
  2. 点击您的个人资料图标,然后选择“Settings”。
  3. 在左侧菜单中,选择“Developer settings” - "Personal access tokens" - "Tokens (classic)"。
  4. 在下拉菜单中,选择“Personal access tokens”。
  5. 点击“Generate new token (classic) - For general use”按钮,再次确认账号密码,填写相应信息,然后勾选所需权限。建议给予尽可能少的权限。

    注意:请勿选择“Generate new token - Fine-grained, repo-scoped”,该 token 不支持 GitHub GraphQL API。

  6. 点击“Generate token”按钮。

创建完成后,您可以使用该 token 来访问 Github GraphQL API。

创建 GraphQL 查询语句

接下来,您可以按照以下步骤使用 Github GraphQL API:

  1. 打开 GraphiQL Explorer,它是一个可视化的 GraphQL 编辑器,可帮助您轻松编写和测试 GraphQL 查询。
  2. 确定要查询的 Github 数据,例如用户信息、仓库信息、组织信息等。
  3. 在 GraphiQL 中编写查询语句,然后通过 Github GraphQL API 进行查询。
  4. 根据查询结果进行开发和测试。

以下是一个示例查询:

query { 
  viewer { 
    login
  }
}

此查询将返回当前授权用户的 Github 登录名:

{
  "data": {
    "viewer": {
      "login": "excing"
    }
  }
}

注意:GraphiQL Explorer 默认拥有用户的大多数权限,但我们创建的 Token 可能仅拥有少数的权限,所以在实际开发中,可能 Explorer 里运行正常,而我们的程序运行则会报错,一般是缺少访问权限,没关系,换上拥有相应权限的 Token 即可。

Golang 请求 GitHub GraphQL API

GitHub GraphQL API 的地址是 https://api.github.com/graphql,请求方法是 POST,返回 JSON 结构体,如下:

func query(body string, token string, result *Body) error {
	query := strings.ReplaceAll(body, "\n", "")
	query = strings.ReplaceAll(query, "\t", " ")
	query = strings.ReplaceAll(query, `"`, `\"`)
	fields := strings.FieldsFunc(query, func(c rune) bool {
		return c == ' '
	})
	query = fmt.Sprintf(`{"query": "query %v" }`, strings.Join(fields, " "))
	req, err := http.NewRequest("POST", "https://api.github.com/graphql", strings.NewReader(query))
	if err != nil {
		return err
	}
	req.Header.Set("Authorization", "bearer "+token)

	response, err := http.DefaultClient.Do(req)
	if err != nil {
		return err
	}
	defer response.Body.Close()

	resBodyBytes, err := ioutil.ReadAll(response.Body)

	if http.StatusOK != response.StatusCode {
		return fmt.Errorf("GraphQL query failed: %v\n%v", response.Status, string(resBodyBytes))
	}

	if err = json.Unmarshal(resBodyBytes, &result); err != nil {
		return err
	}

	if result.Data == nil {
		return fmt.Errorf("GraphQL query error: %v", string(resBodyBytes))
	}

	return nil
}

// Body is Github GraphQL api response body
type Body struct {
	Data *GithubData `json:"data"`
}

// GithubData is Github GraphQL api data
type GithubData struct {
	Viewer       *User         `json:"viewer"`
}

// User is Github user scheme
type User struct {
	Login     string `json:"login"`
}

func main() {
	query = `query { 
		viewer { 
			login
		}
	}`
	githubToken := "your github token"
	var result Body
	err := query(query, githubToken, &result)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(&result.Viewer.Login)
}

一切正常情况下,会打印了你的用户名,在我这里,打印的是我的用户名:excing

TOP
前往 GitHub Discussion 评论