GitHub REST API活用パターン
何ができるか
GitHub REST API は、Web画面でできることのほとんどをプログラムから行えるようにした [[REST API]] です。
curl -H "Authorization: Bearer $TOKEN" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/owner/repo/commits?per_page=100"
実務でよく使う用途は次の3つです。
- 状態の収集 — コミット・PR・Issue を集めて集計する(活動量の可視化、棚卸し)
- 自動化 — Issue の起票、ラベル付け、PRの作成やマージ
- 監視 — 一定期間コミットが無いリポジトリの検出など、定期的な確認
ページングが最初の壁
一覧を返すエンドポイントは、既定で30件しか返しません。per_page=100 にしても100件が上限です。
残りがあるかどうかは、レスポンスの Link ヘッダを見て判断します。 配列の長さが per_page と同じかどうかで判定する実装は、ちょうど割り切れたときに1ページ読み落とします。
Link: <https://api.github.com/...&page=2>; rel="next", <...&page=9>; rel="last"
rel="next" が無くなるまで辿るのが正しい実装です。「取れた件数が想定より少ない」という不具合の多くは、ページングの打ち切りが原因です。
レートリミット
| 認証 | 上限 |
|---|---|
| 未認証 | 60 リクエスト/時 |
| 個人アクセストークン | 5,000 リクエスト/時 |
| GitHub App | インストール数に応じて増える |
さらに REST と GraphQL は別勘定で、検索エンドポイントにはより厳しい別枠があります。
残量はレスポンスヘッダで分かります。
x-ratelimit-remaining: 4832
x-ratelimit-reset: 1755500000 # UNIX時刻
枯渇したときに短い間隔で再試行するのは無駄です。 リセット時刻まで待つのが正しい対処になります。[[レートリミット]] の一般論と同じく、上限に当たってからではなく当たらない設計にするのが本題です。
- 一覧の取得は
per_page=100で回数を減らす - 変更が無ければ再取得しない(
If-None-Matchで304が返ると消費されません) - 差分だけを取る(
sinceパラメータなど)
イベントを取るか、通知を受けるか
「あるリポジトリで何かが起きたら反応したい」という要件には2つの方法があります。
| ポーリング(REST) | [[Webhook]] | |
|---|---|---|
| 仕組み | 定期的に問い合わせる | 起きたときに送られてくる |
| 遅延 | 間隔ぶん遅れる | ほぼ即時 |
| レート消費 | する | しない |
| 受け口 | 不要 | 公開URLが要る |
イベント一覧のAPIは保持期間と件数に上限があり、古いものは取れません。監視間隔がその範囲を超えると取りこぼします。常時受け取りたいなら Webhook、定期的な棚卸しなら REST、という使い分けになります。
実装の作法
Acceptヘッダで版を明示する — 応答の形が変わる更新に備えます([[APIバージョニング]])- 公式クライアントを使う — octokit などはページングとリトライを内蔵しています。自作すると上の落とし穴を全部踏みます
- トークンの権限を絞る — 読み取りだけで足りる用途に書き込み権限を与えません
- [[CI/CD]] のワークフローから呼ぶときは既定のトークンを使う — ワークフローに渡されるトークンは、そのリポジトリに限定されています
関連技術とのつながり
- [[REST API]] — 設計の土台。ページングと認証の作法は他のAPIにも通じる
- [[レートリミット]] — 上限に当たらない設計が本題
- [[Webhook]] — 即時性が要るときの受け取り方
- [[CI/CD]] — ワークフロー内からAPIを呼び、収集や自動化を定期実行する
- [[APIバージョニング]] — 応答の形が変わる更新への備え
- [[GitHub App]] — 個人トークンに頼らず、アプリ名義の短命トークンで API を呼ぶ仕組み
Q: 一覧APIで全件を取得する正しい判定方法はどれ?
- [ ] 返ってきた配列の長さが `per_page` より少なければ最後と判断する
- [x] レスポンスの `Link` ヘッダに `rel="next"` が無くなるまで辿る
- [ ] 常に10ページまで取得する
解説: 件数がちょうど割り切れたときに1ページ読み落とします。件数での判定は避けます。
Q: レートリミットが枯渇したときの正しい対処はどれ?
- [ ] 30秒間隔で再試行を続ける
- [x] `x-ratelimit-reset` の時刻まで待つ
- [ ] 未認証のリクエストに切り替える
解説: 未認証は60/時とさらに厳しくなります。短い間隔の再試行は無駄です。
Q: リポジトリの変化へ即時に反応したいときに向くのはどれ?
- [ ] イベント一覧APIを短い間隔でポーリングする
- [x] Webhookで通知を受け取る
- [ ] 検索APIを使う
解説: イベント一覧は保持期間と件数に上限があり、間隔が広いと取りこぼします。Webhookはレートも消費しません。