[GitHub GraphQL API] プロフィールにピン留めしたリポジトリを取得する方法

3 min read

概要

GitHub のプロフィールにピン留めしたアイテム情報を取得したい。

ピン留めする方法

おさらい。

  1. プロフィールページに移動
    https://github.com/{id}
  2. [Customize your pins]をクリック
  3. [Edit pinned items]というモーダルが開く
  4. 選択して保存

最大 6 つのリポジトリ・Gist をピン留めしてプロフィール上に表示できる。

仕様

  • ピン留めしたリポジトリ情報を API 経由で取得する
  • Gist はピン留めしない(考慮していない)
  • JavaScript(TypeScript)上から扱う

方法

GraphQL API

ピン留めしたアイテム情報を API 経由で取得するためには、GraphQL APIを利用する必要がある。

また、API を扱うには、GitHub のパーソナルアクセストークンが必要になる。アクセストークンの取得方法については、以下の公式ドキュメントで解説があるため、ここでは割愛する。

docs.github.com個人用アクセス トークンを管理する - GitHub Docsコマンド ラインまたは API を使用して GitHub への認証を行うときに、パスワードの代わりに personal access token を使用することができます。

取得したい情報

  • リポジトリ名
  • リポジトリの説明
  • リポジトリの URL
  • スター数
  • フォーク数
  • 利用言語
    • 言語名

実装

api.github.com/graphqlというエンドポイントに対して fetch を利用して認証情報と必要なqueryを POST する。

async function getGitHubPinnedItems() {
  return await fetch("https://api.github.com/graphql", {
    method: "post",
    headers: {
      Authorization: `Bearer ${process.env.GITHUB_ACCESS_TOKEN}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      query: `
      {
        user(login: "hiro0218") {
          pinnedItems(first: 6, types: REPOSITORY) {
            edges {
              node {
                ... on Repository {
                  name
                  description
                  url
                  stargazerCount
                  forkCount
                  languages(first: 1, orderBy: {field: SIZE, direction: DESC}) {
                    nodes {
                      color
                      name
                    }
                  }
                }
              }
            }
          }
        }
      }
      `,
    }),
  })
    .then((response) => response.json())
    .then((x: GitHubGraphQl) => {
      // 型情報は自前で定義した
      return x?.data?.user?.pinnedItems?.edges?.map((x) => {
        const { languages, ...rest } = x.node;
        return { ...rest, languages: languages.nodes.at(0) };
      });
    });
}

user(login: "hiro0218")は指定ユーザーの情報を取得するためのクエリである。そのため、hiro0218は任意の ID で良い。

languagesは複数取得できてしまう。今回は一番利用されている言語情報が 1 件だけ必要だったためlanguages(first: 1, orderBy: {field: SIZE, direction: DESC})という指定をしている。

ウェブ上であれば GitHub ログインをするだけでGitHub GraphQL API のエクスプローラーを利用して、どういった情報が取得できるのか確認可能。