私が歌川です

@utgwkk が書いている

GoでGraphQLクライアントを書くために github.com/hasura/go-graphql-client を使ったら便利だった

あらすじ

Go言語でGraphQL APIを叩くクライアントを書くことがあって、クエリをベタ書きするのはともかく返り値にマッピングされるようなstructの型を用意するのが面倒すぎる。正常系だけならそれでもまだなんとかなるかもしれないけど、異常系のことも考えて書く……となると気が遠くなる。

なんとかならないかと思って探していたら表題のクライアントを見つけた。GitHub - shurcooL/graphql: Package graphql provides a GraphQL client implementation. をフォークして機能追加したライブラリらしい。

github.com

使ってみた

以下のようなGraphQLスキーマがあるとする。実際のスキーマからはだいぶ端折っている。

type Artwork implements Node {
  id: ID!
  title: String!
  caption: String!
  nsfw: Boolean!
  topIllust: Illust
}

type Illust implements Node {
  """The ID of the object."""
  id: ID!
  thumbnailUrl: String!
}

たとえば以下のようなGraphQLクエリを発行したいとする。

query artworkInfoQuery($id: ID!){
  node(id: $id) {
    ... on Artwork {
      title
      caption
      nsfw
      topIllust {
        thumbnailUrl
      }
    }
  }
}

以下のような無名structを作ってあげたら、変数も渡しつつリクエストできる。inline fragmentもシャッと書ける。これだけでGraphQLクエリを手書きする手間、レスポンスのJSONに合わせたstructを作る手間、異常系をハンドリングする手間が1つにまとまった。

graphqlClient := graphql.NewClient(graphqlAPIEndpoint, nil)

var artworkInfoQuery struct {
    Node struct {
        Artwork struct {
            Title   graphql.String
            Caption graphql.String
            Nsfw    graphql.Boolean
            TopIllust struct {
                ThumbnailUrl graphql.String
            }
        } `graphql:"... on Artwork"`
    } `graphql:"node(id: $id)"`
}
err = graphqlClient.Query(context.Background(), &artworkInfoQuery, map[string]interface{}{
    "id": graphql.ID(artworkID),
})
if err != nil {
    log.Print(err)
    return
}

ちょっとGraphQL APIを叩いてなんかやりたい、ぐらいのときには愛用することになりそう。