【GitHub API】gist のスター数を取得する【stargazers を GitHub CLI（gh コマンド）で取得する】

# Get the number of stars for a "gist" repository

> GitHub の HTML を[スクレイピング](https://ja.wikipedia.org/wiki/%E3%82%A6%E3%82%A7%E3%83%96%E3%82%B9%E3%82%AF%E3%83%AC%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0)せずに、**`gist` に付いたスター数（「いいね」数、`stargazers`）を API を叩いて取得したい**。

マイクロ git とも言える、[GitHub Gist](https://docs.github.com/ja/get-started/writing-on-github/editing-and-sharing-content-with-gists/creating-gists) をブログ記事の [CMS](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%B3%E3%83%86%E3%83%B3%E3%83%84%E7%AE%A1%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0) のバックエンド（DB 替わり）に使おうと思い、各記事に付いたスター数を表示したかったのです。

しかし、[GitHub API v3 の Gists エンドポイント](https://docs.github.com/en/rest/gists/gists) には「星が付いているか、否か」の "[/gists/{gist_id}/star](https://docs.github.com/en/rest/gists/gists#check-if-a-gist-is-starred)" エンドポイントしかありませんでした。[「github API "gist" how to get stargazers」でググって](https://www.google.com/search?q=github+API+%22gist%22+how+to+get+stargazers)も、HTML をスクレイピングする方法ばかりで、レイアウト変更（クラス名変更）のたびに追随するのも大変です。

API で叩いて取得する方法がすぐにヒットしなかったので、自分のググラビリティとして。

> Go 用のパッケージも作りました

https://github.com/KEINOS/go-gisty

> ステータス・バッジの老舗である、天下の [Shields.io](https://shields.io) も対応しました。

https://shields.io/badges/git-hub-gist-stars

## TL; DR <sub><sup><sub><sup>（今北産業）</sup></sub></sup></sub>

1. GitHub API [v4](https://ja.wikipedia.org/wiki/GraphQL#GitHub_API) の [GraphQL API](https://docs.github.com/en/graphql) を使う。
1. [GraphQL](https://ja.wikipedia.org/wiki/GraphQL) で [Viewer クエリ](https://docs.github.com/en/graphql/reference/queries#viewer) --> [Gist オブジェクト](https://docs.github.com/en/graphql/reference/objects#gist) --> `stargazerCount` フィールドを参照する。
1. [GitHub CLI](https://docs.github.com/en/github-cli/github-cli/about-github-cli) の [gh コマンド](https://cli.github.com/) であれば `gh api graphql` サブコマンドで GraphQL のリクエストができる。
```bash
#!/bin/bash

QUERY='
query {
  viewer {
    gist (name: "5b10b34f87955dfc86d310cd623a61d1" ) {
        stargazerCount
    }
  }
}
'
TEMPLATE='{{.data.viewer.gist.stargazerCount}}'

# 要 `gh auth login` 済み
gh api graphql -f query="${QUERY}" --template="${TEMPLATE}"

# Output:
# 2
```

## TS; DR

```bash
#!/bin/bash
# shellcheck disable=SC2016

# 最初の 10 件の gist のスター数を取得する例
QUERY1='
query {
  viewer {
    gists (first: 10, orderBy: {field: CREATED_AT, direction: DESC} ) {
        nodes {
            createdAt
            description
            name
            pushedAt
            stargazers (first: 100) {
            totalCount
            edges {
                node {
                id
                }
            }
            }
            updatedAt
        }
    }
  }
}
'
TEMPLATE1='
  {{- range $repo := .data.viewer.gists.nodes -}}
    {{- printf "name: %s - stargazers: %v\n" $repo.name $repo.stargazers.totalCount -}}
  {{- end -}}
'

gh api graphql -f query="${QUERY1}" --paginate --template="${TEMPLATE1}"

echo "----------------------------------"

# 指定した gist ID のスター数を取得する例
QUERY2='
query {
  viewer {
    gist (name: "5b10b34f87955dfc86d310cd623a61d1" ) {
        name
        stargazerCount
    }
  }
}
'
TEMPLATE2='
    {{- printf "name: %s - stargazers: %v\n" .data.viewer.gist.name .data.viewer.gist.stargazerCount -}}
'

gh api graphql -f query="${QUERY2}" --paginate --template="${TEMPLATE2}"

# Output:
# name: 7101f542be23e5048198e2a27c3cfda8 - stargazers: 0
# name: d5b9800c636dd78defa4f15894d54d29 - stargazers: 0
# name: e915aa8c01dd438e3ffd79b05f15a4ff - stargazers: 0
# name: 83e82d243b9b3d9ffbf370010ad658c3 - stargazers: 0
# name: 9cbad9941ad797b8d75123e40f7fd4c8 - stargazers: 0
# name: 76857bc6339515d7144e00f17adb1090 - stargazers: 1
# name: 5fd419de98e58b650ad279d6c1266179 - stargazers: 1
# name: cb4dbde222fb494405bb522692235456 - stargazers: 1
# name: f15d018ceb6d2a2103c581b41530ad49 - stargazers: 0
# name: a821517a85992fe329489db2ce32bd56 - stargazers: 0
# ----------------------------------
# name: 5b10b34f87955dfc86d310cd623a61d1 - stargazers: 2
```

## 参考文献

- GitHub API v4 ([GraphQL API](https://docs.github.com/en/graphql))
    - [Gist object](https://docs.github.com/en/graphql/reference/objects#gist)

- [Simple User Gists Query Using GitHub GraphQL API (v4 API)](https://gist.github.com/jamesluberda/d73376298e22e3fc4abbca590b97d5e0) @ Gist
- [script.sh](https://github.com/cli/cli/blob/trunk/pkg/cmd/extension/ext_tmpls/script.sh) extension | cmd | GitHub CLI @ GitHub
- [Get GitHub Gist Stargazer Count](https://stackoverflow.com/questions/31199470/get-github-gist-stargazer-count/74120020) @ StackOverflow
- [GitHub Search API: Get the number of stars for a repository](https://gist.github.com/jasonrudolph/6057563?permalink_comment_id=2896930#gistcomment-2896930) @ Gist