只需要创建用于GitHub GraphQL查询的结构体,它就可以将响应的JSON进行映射的Go库“githubql”
我使用Go语言的Github API的GraphQL客户端githubql。
如何使用GitHubQL
基本上只需根据GraphQL的查询和修改定义相应的Go结构体。
我们先来看一下 GitHub GraphQL 页面上提供的示例。
对于以下这样简单的查询,
query {
viewer {
login
createdAt
}
}
用这种方式定义结构体
var query struct {
Viewer struct {
Login githubql.String
CreatedAt githubql.DateTime
}
}
当执行client.Query时,返回值中包含了Github的GraphQL API的结果。
err := client.Query(context.Background(), &query, nil)
if err != nil {
// Handle error.
}
fmt.Println(" Login:", query.Viewer.Login)
fmt.Println("CreatedAt:", query.Viewer.CreatedAt)
本次尝试的查询(适用于GraphQL Explorer)
您可以在此处轻松查看GitHub的GraphQL API的执行结果:
https://developer.github.com/v4/explorer/
我写了一个查询,可以从Github中提取出与GraphQL相关的5个仓库以及它们所使用的语言。
query {
search(query: "GraphQL", first: 5, type: REPOSITORY) {
edges {
node {
... on Repository {
nameWithOwner,
url,
languages(first:5) {
edges {
node {
... on Language {
name,
color
}
}
}
}
}
}
}
}
}
结果
{
"data": {
"search": {
"edges": [
{
"node": {
"nameWithOwner": "facebook/graphql",
"url": "https://github.com/facebook/graphql",
"languages": {
"edges": [
{
"node": {
"name": "Shell",
"color": "#89e051"
}
}
]
}
}
},
{
"node": {
"nameWithOwner": "graphql-go/graphql",
"url": "https://github.com/graphql-go/graphql",
"languages": {
"edges": [
{
"node": {
"name": "Go",
"color": "#375eab"
}
}
]
}
}
},
・・・以下省略
如果使用GitHubQL编写的话
如果使用githubql在Go中编写上述查询,将如下所示。
使用 Github 的令牌对客户端进行初始化。
src := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: os.Getenv("GITHUB_TOKEN")},
)
httpClient := oauth2.NewClient(context.Background(), src)
client := githubql.NewClient(httpClient)
接下来,我们定义Repository和Language的结构体。
type Language struct {
Name githubql.String
Color githubql.String
}
type Repository struct {
NameWithOwner githubql.String
Url githubql.String
Languages struct {
Nodes []struct {
Language `graphql:"... on Language"`
}
} `graphql:"languages(first: 5)"`
}
当您想要指定 GraphQL 的参数时,可以在结构体上添加标签,例如 graphql:”… on Language”。
在中国,您可以将Search定义为结构体。起初我并不理解这一点,所以有些困惑。之前的Repository定义可以嵌套在Search中进行编写,但是这次我选择将其分开编写。
var query struct {
Search struct {
Nodes []struct {
Repository `graphql:"... on Repository"`
}
} `graphql:"search(first: 5, query: $q, type: $searchType)"`
}
当使用查询参数来传递给Search时,我们可以创建一个map并进行传递。
variables := map[string]interface{}{
"q": githubql.String("GraphQL"),
"searchType": githubql.SearchTypeRepository,
}
err := client.Query(context.Background(), &query, variables)
这是完整的源代码。
package main
import (
"golang.org/x/oauth2"
"os"
"fmt"
"context"
"github.com/shurcooL/githubql"
)
func main() {
src := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: os.Getenv("GITHUB_TOKEN")},
)
httpClient := oauth2.NewClient(context.Background(), src)
client := githubql.NewClient(httpClient)
type Language struct {
Name githubql.String
Color githubql.String
}
type Repository struct {
NameWithOwner githubql.String
Url githubql.String
Languages struct {
Nodes []struct {
Language `graphql:"... on Language"`
}
} `graphql:"languages(first: 5)"`
}
var query struct {
Search struct {
Nodes []struct {
Repository `graphql:"... on Repository"`
}
} `graphql:"search(first: 5, query: $q, type: $searchType)"`
}
variables := map[string]interface{}{
"q": githubql.String("GraphQL"),
"searchType": githubql.SearchTypeRepository,
}
err := client.Query(context.Background(), &query, variables)
if err != nil {
fmt.Println(err)
}
for _, repo := range query.Search.Nodes {
fmt.Println("---------")
fmt.Println(repo.NameWithOwner)
fmt.Println(repo.Url)
for _, lang := range repo.Languages.Nodes {
fmt.Println(lang.Name)
fmt.Println(lang.Color)
}
}
}
执行结果
在查询中定义的结构体中,GraphQL API的响应JSON被映射。
---------
facebook/graphql
https://github.com/facebook/graphql
Shell
#89e051
---------
graphql-go/graphql
https://github.com/graphql-go/graphql
Go
#375eab
---------
Youshido/GraphQL
https://github.com/Youshido/GraphQL
PHP
#4F5D95
---------
graphql-elixir/graphql
https://github.com/graphql-elixir/graphql
Elixir
#6e4a7e
Erlang
#B83998
---------
GraphQLSwift/GraphQL
https://github.com/GraphQLSwift/GraphQL
Swift
#ffac45
以上就是。
请参考
-
- https://github.com/shurcooL/githubql
- https://github.com/shurcooL/graphql