只需要创建用于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
广告
将在 10 秒后关闭
bannerAds