使用graphql-client gem来访问Github API v4

代码

在特定的代码仓库中获取特定成员在特定日期之后被合并的PR清单。

source 'https://rubygems.org'

gem 'graphql-client' # 0.12.1
#! /usr/bin/env ruby

require 'graphql/client'
require 'graphql/client/http'

h = GraphQL::Client::HTTP.new('https://api.github.com/graphql') do
  def headers(context)
    {
      "Authorization" => "Bearer #{ENV['ACCESS_TOKEN']}"
    }
  end
end
s = GraphQL::Client.load_schema(h)
c = GraphQL::Client.new(schema: s, execute: h)
Q = c.parse <<-GraphQL
query($after: String) {
  repository(owner:"our_company", name:"awesome_project") {
    pullRequests(first: 100, states: [MERGED], orderBy: {field: UPDATED_AT, direction: DESC}, after: $after) {
      edges {
        cursor
        node {
          number
          title
          updatedAt
          mergedAt
          author {
            login
          }
        }
      }
    }
  }
}
GraphQL

all_nodes = []
after = nil
loop do
  r = c.query(Q, variables: { after: after })
  nodes = r.data.repository.pull_requests.edges.map(&:node)
  nodes_in_time = nodes.select { |n| Time.parse(n.updated_at) > Time.new(2017, 10, 30) }
  all_nodes += nodes_in_time.select { |n| %w(alice bob carol).include?(n.author.login) }
  break if nodes.size > nodes_in_time.size
  after = r.data.repository.pull_requests.edges.last.cursor
end

puts all_nodes.map { |n| "##{n.number}\t#{n.author.login}\t#{n.merged_at}\t#{n.title}" }

多样的解释

    • アクセストークンはPersonal access tokensのページで作れる

 

    • Qが定数なのはgraphql-clientの仕様で、queryメソッドに引数で渡すクエリ文字列が定数で無かった場合はエラーになる

 

    • orderByに何を指定したら良いかはドキュメントにはほとんど書かれていないがExplorerで適当に打つと補完されるのでわかる

 

    • 1回の取得件数が100件までなので、複数回に分けて取得する必要がある

 

    • edgeとnodeとcursorの仕組みはgraphQLではスタンダードとのこと

cursorを指定してここ以降を取得、とやることでデータを取得していく

結果のオブジェクトはHashieよろしくメソッドで項目にアクセスできるが、元がmergedAtのようにcamelCaseであるものはmerge_atのようにsnake_caseのメソッド名になる

广告
将在 10 秒后关闭
bannerAds