Claude CodeでFastAPIバックエンドを構築する — 型ヒントを軸にした実装フロー
Claude CodeでFastAPIバックエンドを作る際の環境構築、CLAUDE.mdや公式Skillでの型ヒント規約の固定、PostToolUseフックでの型チェック自動化までをまとめます。
Claude CodeでFastAPIバックエンドを作るとは
Claude CodeでFastAPIバックエンドを作るとは、型ヒントを軸にしたFastAPIの設計をClaude Codeに理解させ、CLAUDE.mdや.claude/rules/で規約を固定しながら実装させる進め方です。FastAPIはPythonの型ヒントからリクエストの検証・ドキュメント生成・エディタ補完を自動で組み立てるフレームワークで、この型ヒントはそのままClaude Codeが読む仕様にもなります。
FastAPIの公式ドキュメントは、コードブロックをそのままコピーして動く実例として案内しており、エディタで書いて初めて「書く量の少なさ・自動の型チェック・補完」の恩恵が分かるとしています。この型情報はエディタだけでなくClaude Codeにも同じ形で見えるため、型ヒントが揃っているほどClaude Codeが生成するコードも仕様からずれにくくなります。
FastAPIには、AIコーディングエージェント向けの公式Skillも用意されています。uvx library-skillsでインストールでき、Claude Codeを含む複数のエージェントに対応します。この記事では、環境構築から公式Skillの導入、規約の固定、実行と検証、型チェックの自動化までを順に扱います。
環境をセットアップする
最初にFastAPIのプロジェクトを作り、公式Skillを導入します。FastAPIの公式ドキュメントはuvでのセットアップを案内しています。
uv init awesome-project --bare
cd awesome-project
uv add "fastapi[standard]"uv add "fastapi[standard]"は、FastAPI Cloudへのデプロイに使うfastapi-cloud-cliを含む標準の依存関係一式を入れます。これらの追加依存が不要ならuv add fastapiだけで済み、fastapi-cloud-cliだけを外したいならuv add "fastapi[standard-no-fastapi-cloud-cli]"を使います。
続けて公式Skillを導入します。FastAPIに同梱されたlibrary-skillsコマンドが、インストール済みのFastAPIのバージョンに合わせたガイダンスを生成します。
uvx library-skillsインストール先を聞かれたら.claude/skillsを選びます。Codex・Cursor・GitHub Copilot・Gemini CLIなど他のエージェントにも対応していますが、この記事ではClaude Codeでの利用を前提にします。プロジェクトのFastAPIを更新すると、このSkillの内容もそのバージョンに追随します。
uvを使わず、既存の仮想環境にpipでインストールしたい場合はpip install "fastapi[standard]"でも導入できます。この場合はライブラリの依存解決とロックファイルの管理を自分で行う必要があり、公式ドキュメントも仮想環境を手動で作成・有効化する前提の手順として案内しています。
開発サーバーの起動はfastapi devです。
uv run fastapi dev起動するとhttp://127.0.0.1:8000/docsに自動生成されたAPIドキュメントが立ち上がります。ここまでが済んだ状態から、Claude Codeにエンドポイントの実装を任せていきます。VS CodeのDevContainerやCodespaces上で環境を作る場合の手順はClaude Code CodespacesでDevContainer開発を始める手順にまとめています。
CLAUDE.mdと.claude/rules/で型ヒントの規約を固定する
型ヒントはFastAPIが自動で検証・ドキュメント化する仕組みの土台ですが、書き方が揃っていなければ恩恵は半減します。CLAUDE.mdは会話の開始時に毎回読み込まれるファイルで、プロジェクト全体に常に効かせたい規約を置く場所です。
# API実装の規約
- リクエスト・レスポンスは必ずPydanticモデルの型ヒントで表現する
- パスパラメータには具体的な型(str, int, UUID等)を付ける
- 生のdictやAnyを返り値の型に使わない規約が増えてきたら.claude/rules/ディレクトリに分割し、対象ファイルを絞って読み込ませます。pathsフロントマターにglobパターンを指定すると、Claudeが該当パスのファイルを読んだときだけそのルールが適用されます。
---
paths:
- "app/api/**/*.py"
- "app/schemas/**/*.py"
---
# APIエンドポイントの規約
- エンドポイント関数の引数と返り値に型ヒントを必ず付ける
- ステータスコードは`response_model`と`status_code`で明示する
- 例外は`HTTPException`で送出し、素の`Exception`を投げないpathsのglob展開には上限があります。ルール1件あたり展開後のパターン数1,000個・4MiBまでの予算が共有され、{}によるブレース展開はグループごとに掛け算で増えるため、拡張子の書き分けが多いルールほど予算を圧迫します。予算を超えるパターンは展開されないまま扱われ、そのパターンはマッチしません。
複数プロジェクトで同じ規約を使い回すなら、~/.claude/rules/に置いた共有ルールをシンボリックリンクで各プロジェクトの.claude/rules/にリンクする方法もあります。バックエンドの設計を仕様から固めてから実装に入りたい場合は、仕様駆動開発(cc-sdd)の実践の進め方と組み合わせても機能します。
/runと/verifyでエンドポイントの動作を確認する
Claude Codeには、アプリを実際に起動して変更を確認するためのバンドル済みSkillが3つあります。
| Skill | 役割 |
|---|---|
/run | 役割アプリを起動し、動いている状態を見せる |
/verify | 役割アプリをビルド・起動し、テストや型チェックに頼らず変更が意図どおり動くかを確認する |
/run-skill-generator | 役割/runと/verifyにプロジェクト固有の起動方法を教える |
/runと/verifyは設定なしで動きます。プロジェクトの種類(CLI・サーバー・ブラウザー主体)や、READMEとpackage.json、Makefileの中身から起動方法を推測するためです。FastAPIのようにfastapi devだけで起動する構成なら、この推測はほぼ外れません。
一方で、DBマイグレーションやenvファイル、複数ステップのビルドが要る構成では推測が外れやすくなります。そこで使うのが/run-skill-generatorです。クリーンな環境から実際にアプリを起動させ、必要だったインストールコマンドや環境変数、起動スクリプトを.claude/skills/run-<name>/にプロジェクト固有のSkillとして記録します。一度記録すれば、/runや/verifyだけでなくリポジトリ内の他のエージェントも同じ手順に従います。ビルドや起動の手順が変わったときは、このコマンドを再度実行します。
/verify自身も、起動に失敗した経路を学んだときにリポジトリルートの.claude/skills/verify/SKILL.mdへ手順を書き足します(Claude Code v2.1.200以降)。以降の/verifyはバンドル版の代わりにこの記録済みSkillに従うため、コミットしても毎セッション同じ差分が出続けることはありません。
PostToolUseフックで型チェックを自動化する
/verifyはまとまった単位で動作を確認する手段ですが、編集のたびに型の矛盾を検出したい場合はPostToolUseフックを使います。テストの合否を締め条件にする進め方はClaude CodeでのTDDの回し方で扱っていますが、ここでは型チェックに絞った例を示します。
.claude/settings.jsonに、EditまたはWriteツールの実行後に発火するフックを登録します。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/type-check.sh"
}
]
}
]
}
}スクリプト側で、編集されたファイルが.pyかどうかを見てからmypyを走らせます。
#!/usr/bin/env bash
input=$(cat)
file=$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty')
if [[ "$file" == *.py ]]; then
if ! uv run mypy "$file" --ignore-missing-imports; then
echo "型エラーが残っています。修正してから次に進んでください。" >&2
exit 2
fi
fi終了コード2を返すと、標準エラー出力の内容がその場でClaudeへのフィードバックとして渡ります。
フックの置き場所はスコープを決めます。.claude/settings.jsonはプロジェクト単位でリポジトリにコミットでき、チーム全員に同じフックを配ります。個人だけの設定なら.claude/settings.local.jsonに置くと、Claude Code側が自動でgitignore対象にします。mypyをこのフックで走らせる前提として、uv add --dev mypyのように開発用依存として追加しておく必要があります。
Claude Codeでの実装フロー使い分け早見表
ここまでの要素は役割が異なります。どれか1つで済ませるのではなく、場面に応じて組み合わせます。
| 用途 | 使うもの | 向く場面 |
|---|---|---|
| 型ヒントの規約を常に効かせる | 使うものCLAUDE.md / .claude/rules/ | 向く場面エンドポイント全体で守らせたい規約 |
| FastAPI固有の実装知識を都度参照する | 使うものFastAPI公式Skill | 向く場面Pydanticモデルやルーティングの書き方に迷うとき |
| 起動して動作を目で確認する | 使うもの/run /verify | 向く場面変更がAPIとして動くかどうかの確認 |
| 起動手順をプロジェクトに固定する | 使うもの/run-skill-generator | 向く場面DBやenvが要って推測が外れる構成 |
| 編集のたびに型エラーを検出する | 使うものPostToolUseフック | 向く場面型ヒントの矛盾を即座に拾いたいとき |
よくあるつまずき
/runと/verifyの推測が外れる
DBへの接続やenvファイルの読み込みが要る構成だと、README頼みの推測は失敗しやすくなります。毎回同じ理由で外れるなら、/run-skill-generatorで起動手順を一度記録し、以降は推測させない形に変えます。
.claude/rules/のpathsが効かない
pathsのglobパターンに[が含まれ、かつブラケット表現として解釈できない形になっていると、そのパターンは何にもマッチしなくなります。ファイル名に角かっこを使う場合は\[のようにエスケープします。ルール全体の展開予算(1,000パターン・4MiB)を超えたパターンも同様にマッチしません。
Bash経由で生成したファイルにフックが効かない
alembic revision --autogenerateのようにBashコマンドがマイグレーションファイルを生成した場合を考えます。この場合EditやWriteツールを経由していないため、matcher: "Edit|Write"のPostToolUseフックは発火しません。Bashコマンドの結果を検証したいときは、matcherをBashにした別のフックを用意します。
disableBundledSkillsで/runと/verifyが消える
この設定を有効にしていると、/runや/verifyを含むバンドル済みSkillそのものが使えなくなります。チームの設定を引き継いだプロジェクトで両コマンドが見当たらないときは、まずこの設定を確認します。
.claude/rules/と.claude/skills/の役割を混同する
どちらも.claude/配下に置きますが、性質が違います。ルールはセッション開始時や対象ファイルを開いたタイミングで常に文脈に読み込まれるのに対し、Skillは呼び出したとき、またはClaudeが関連すると判断したときだけ読み込まれます。型ヒントの規約のように常に効かせたい内容はルールへ、FastAPI固有の実装知識のように必要なときだけ参照したい内容はSkillへ分けると、常駐する文脈量を抑えられます。
まとめ
Claude CodeでFastAPIバックエンドを作る流れは、いくつかの要素の積み重ねです。uvでの環境構築とFastAPI公式Skillの導入から始まり、CLAUDE.mdと.claude/rules/で型ヒントの規約を固定します。そのうえで/runと/verifyで動作を確認し、必要ならPostToolUseフックで型チェックを編集単位に落とし込みます。
DBやenvファイルが絡んで/runの推測が外れる構成では、/run-skill-generatorで起動手順を先に記録しておくと以降の往復が減ります。完成したバックエンドをコンテナ化して開発・本番のクラスタに載せる段階に進むなら、Docker/Podman/Kubernetes MCPの選び方が次の分岐点の整理に役立ちます。