はじめに
どうも、Caruです。
最近、GitHubのAPIを使ってブログを構築する方法について記事を書いたのですが、その中で、この機構をまとめてAPIとして提供したいと思いました。 Next.jsで作るのも悪くはないのですが、型定義とかGraphQLとか、意外とゴチャついてしまうんですよね...。
そこで、GitHubでホストしたMarkdown記事を配信するためのFastAPIベースのバックエンドライブラリ「FastAPI GitHub Blog」を作成しました。
同じように「GitHubのリポジトリだけでブログを回したい」「でもAPIを直接触るのは面倒」という人が、さらっと導入できるようにしています。
FastAPI GitHub Blogとは
FastAPI GitHub Blogは、GitHubでホストしたMarkdown記事を配信するためのFastAPIベースのバックエンドライブラリです。READMEではなく、使ってみた感触を中心にまとめてみます。
主な特徴はこんな感じ:
- FastAPI + async でサクッと動く。リッチな機能よりも「欲しいものだけ」を詰め込んだ感じ
- GraphQLでまとめて取得。フラットなarticlesディレクトリを想定し、Frontmatterをその場でパース
- 読了時間やタグを自動正規化。GraphQL→Markdown→JSONの変換を全部裏でやる
- キャッシュ + Webhook。GitHubからpush通知が来たら勝手にinvalidateしてくれる
- 画像プロキシ。GitHub上の画像をCDN経由っぽく返せる(必要ならAuthorizationヘッダーも引き継ぎ)
どんな人に刺さる?
- NotionやCMSを使うほどでもないけど、GitHub管理のブログをAPI経由で配信したい人
- フロントはNext.js/Remixで書いていて、バックエンドは極力薄く済ませたい人
- GitHubのレート制限やトークン管理を全部サーバー側に押し込みたい人
- 「GraphQLで取得 → Frontmatterをパース → メタデータを整形」みたいな導線を自作するのが面倒な人
「GitHub + Markdown」の良さはそのままに、配信周りの面倒を肩代わりする感じのツールです。
アーキテクチャをざっくり
やっていることはシンプルで、以下の3ピースを繋いでいます。
- FastAPI:
/v1/articlesや/v1/images/{path}を生やして、フロントから叩いてもらう - 内部キャッシュ: 記事メタデータや本文をそのまま保持。Webhookで無効化
- GitHubリポジトリ: Markdownや画像を置いておく唯一のストレージ
GitHubにpushが来たらWebhookでキャッシュを飛ばし、必要なものだけGraphQL経由で取りにいくスタイル。
APIキーをフロントに渡さなくていいし、キャッシュでGitHubのレート制限にも耐えやすくなります。
使い方のイメージ
具体的なコマンド列はREADMEへ任せるとして、実際の導入フローはこんな感じです。
- リポジトリをcloneして
.envにGitHubのトークンやリポジトリ名を入れる uv run appでFastAPIを起動- フロント側から
GET /v1/articlesで記事一覧を取得し、/v1/articles/{slug}で本文を含む記事データを取る - 画像は
GET /v1/images/{path}をそのままimgタグに貼る - GitHubのWebhookを
/v1/webhooks/githubに向ければ、自動でキャッシュが最新化される
GraphQLのクエリを書いたり、Frontmatterのパーサーを持ったりといった雑務を全部ラップしたので、
「とりあえず動かしたい」人はFastAPIを立ち上げるだけでほぼ完了です。
推しポイント
-
素のGitHubリポジトリがCMSになる
データベースもストレージも不要。記事管理フローをこれ以上シンプルにするのは難しいはず。 -
GraphQLでN+1問題を潰す
記事一覧と本文を1クエリで取れるので、RESTでファイル列挙→個別取得…という面倒がない。 -
Webhookによる自動リフレッシュ
手動デプロイや再fetchを意識しなくて良い。GitHub上で記事を更新すれば勝手に最新化される。 -
画像プロキシで安全に配信
Privateリポジトリに置いた画像でも、フロントからは通常のURLとして扱える。
今後やりたいこと(TODO)
今後は以下のような機能があったら面白くなるかなと思います:
- GraphQLのエラー処理強化: GitHubのレート制限やネットワーク例外を拾って自動リトライ&バックオフする仕組みを入れたい
- Webhook署名検証のテスト追加:
X-Hub-Signature-256の計算ロジックをPytestで再現し、シークレットが変わっても安全に運用できるようにする - 画像プロキシのキャッシュ戦略: CDNを噛ませつつEtagを尊重した304レスポンスを返せるようにして、帯域とレスポンスを最適化したい
- 監視用メトリクスの公開:
/metricsでキャッシュヒット率やGitHub API呼び出し回数をPrometheusへ流し、ボトルネックを可視化する
まとめ
FastAPI GitHub Blogは、GitHubに記事を置いている人が「APIっぽく配信したい」と思ったときにそのまま差し込めるバックエンドです。
ベタ書きのREADMEではなく、使ってみた肌感・欲しかった要素を中心に紹介しました。
似たような構成を考えている方は、ぜひ参考にしてもらえるとうれしいです。
最後までご覧いただきありがとうございました!
リポジトリ
⭐️Starしていただけると励みになります!(小声)
はじめに
どうも、Caruです。
最近、GitHubのAPIを使ってブログを構築する方法について記事を書いたのですが、その中で、この機構をまとめてAPIとして提供したいと思いました。 Next.jsで作るのも悪くはないのですが、型定義とかGraphQLとか、意外とゴチャついてしまうんですよね...。
そこで、GitHubでホストしたMarkdown記事を配信するためのFastAPIベースのバックエンドライブラリ「FastAPI GitHub Blog」を作成しました。
同じように「GitHubのリポジトリだけでブログを回したい」「でもAPIを直接触るのは面倒」という人が、さらっと導入できるようにしています。
FastAPI GitHub Blogとは
FastAPI GitHub Blogは、GitHubでホストしたMarkdown記事を配信するためのFastAPIベースのバックエンドライブラリです。READMEではなく、使ってみた感触を中心にまとめてみます。
主な特徴はこんな感じ:
- FastAPI + async でサクッと動く。リッチな機能よりも「欲しいものだけ」を詰め込んだ感じ
- GraphQLでまとめて取得。フラットなarticlesディレクトリを想定し、Frontmatterをその場でパース
- 読了時間やタグを自動正規化。GraphQL→Markdown→JSONの変換を全部裏でやる
- キャッシュ + Webhook。GitHubからpush通知が来たら勝手にinvalidateしてくれる
- 画像プロキシ。GitHub上の画像をCDN経由っぽく返せる(必要ならAuthorizationヘッダーも引き継ぎ)
どんな人に刺さる?
- NotionやCMSを使うほどでもないけど、GitHub管理のブログをAPI経由で配信したい人
- フロントはNext.js/Remixで書いていて、バックエンドは極力薄く済ませたい人
- GitHubのレート制限やトークン管理を全部サーバー側に押し込みたい人
- 「GraphQLで取得 → Frontmatterをパース → メタデータを整形」みたいな導線を自作するのが面倒な人
「GitHub + Markdown」の良さはそのままに、配信周りの面倒を肩代わりする感じのツールです。
アーキテクチャをざっくり
やっていることはシンプルで、以下の3ピースを繋いでいます。
- FastAPI:
/v1/articlesや/v1/images/{path}を生やして、フロントから叩いてもらう - 内部キャッシュ: 記事メタデータや本文をそのまま保持。Webhookで無効化
- GitHubリポジトリ: Markdownや画像を置いておく唯一のストレージ
GitHubにpushが来たらWebhookでキャッシュを飛ばし、必要なものだけGraphQL経由で取りにいくスタイル。
APIキーをフロントに渡さなくていいし、キャッシュでGitHubのレート制限にも耐えやすくなります。
使い方のイメージ
具体的なコマンド列はREADMEへ任せるとして、実際の導入フローはこんな感じです。
- リポジトリをcloneして
.envにGitHubのトークンやリポジトリ名を入れる uv run appでFastAPIを起動- フロント側から
GET /v1/articlesで記事一覧を取得し、/v1/articles/{slug}で本文を含む記事データを取る - 画像は
GET /v1/images/{path}をそのままimgタグに貼る - GitHubのWebhookを
/v1/webhooks/githubに向ければ、自動でキャッシュが最新化される
GraphQLのクエリを書いたり、Frontmatterのパーサーを持ったりといった雑務を全部ラップしたので、
「とりあえず動かしたい」人はFastAPIを立ち上げるだけでほぼ完了です。
推しポイント
-
素のGitHubリポジトリがCMSになる
データベースもストレージも不要。記事管理フローをこれ以上シンプルにするのは難しいはず。 -
GraphQLでN+1問題を潰す
記事一覧と本文を1クエリで取れるので、RESTでファイル列挙→個別取得…という面倒がない。 -
Webhookによる自動リフレッシュ
手動デプロイや再fetchを意識しなくて良い。GitHub上で記事を更新すれば勝手に最新化される。 -
画像プロキシで安全に配信
Privateリポジトリに置いた画像でも、フロントからは通常のURLとして扱える。
今後やりたいこと(TODO)
今後は以下のような機能があったら面白くなるかなと思います:
- GraphQLのエラー処理強化: GitHubのレート制限やネットワーク例外を拾って自動リトライ&バックオフする仕組みを入れたい
- Webhook署名検証のテスト追加:
X-Hub-Signature-256の計算ロジックをPytestで再現し、シークレットが変わっても安全に運用できるようにする - 画像プロキシのキャッシュ戦略: CDNを噛ませつつEtagを尊重した304レスポンスを返せるようにして、帯域とレスポンスを最適化したい
- 監視用メトリクスの公開:
/metricsでキャッシュヒット率やGitHub API呼び出し回数をPrometheusへ流し、ボトルネックを可視化する
まとめ
FastAPI GitHub Blogは、GitHubに記事を置いている人が「APIっぽく配信したい」と思ったときにそのまま差し込めるバックエンドです。
ベタ書きのREADMEではなく、使ってみた肌感・欲しかった要素を中心に紹介しました。
似たような構成を考えている方は、ぜひ参考にしてもらえるとうれしいです。
最後までご覧いただきありがとうございました!
リポジトリ
⭐️Starしていただけると励みになります!(小声)