FastAPIは型ヒントとバリデーション、自動OpenAPIドキュメントを備えたモダンなPythonフレームワークです。基本的な使い方と適用例を学びましょう。

FastAPIは、明確なコードと自動ドキュメントを備えた、素早くAPIを構築できるPythonのフレームワークです。小さな関数(「エンドポイント」と呼ばれます)を書き、APIが受け取るデータと返すデータを宣言すると、FastAPIがルーティング、バリデーション、JSONレスポンス生成などの「配線」を処理します。
APIは、あるソフトウェアが別のソフトウェアと会話するためのURLの集合です。
例えば、あなたのスマホの天気アプリがGET /weather?city=BerlinのようなURLを呼ぶかもしれません。サーバーは温度や予報などの構造化データ(通常はJSON)で応答します。スマホアプリはサーバーのデータベースに直接アクセスする必要はなく、APIに問い合わせて結果を表示するだけです。
FastAPIはそうしたURLとレスポンスをPythonで簡単に作れるようにします。
非同期の専門家である必要はありません。まずはシンプルなエンドポイントを書き、必要に応じて高度なパターンを取り入れていけます。
FastAPIは、PythonでAPIを作る際に人々が日常的に直面する摩擦を多く取り除くため、急速に受け入れられました。
従来のAPIプロジェクトは、セットアップが遅く多くの「配線」作業が必要になることが多いです:
FastAPIのコア機能はこれらの問題に直接対処するため、チームはフレームワークのボイラープレートに悩まされる時間を減らし、エンドポイント設計に集中できます。
FastAPIはPythonの型ヒントを重視します。フィールドをint、オプション、あるいはlist[Item]のように宣言すると、FastAPIはその情報を使って入力を検証し、出力を整えます。
これにより、IDを文字列として扱ったり数値として扱ったりするようなミスが減り、一貫したエンドポイント挙動が促されます。依然としてPythonですが、関数シグネチャに明確な期待が組み込まれます。
APIのスキーマがコードから派生するため、FastAPIは対話型のドキュメント(OpenAPI + Swagger UI/ReDoc)を自動で生成できます。これは協業において重要です:フロントエンド開発者、QA、統合担当者がエンドポイントを試し、正確なモデルを待たずに確認できます。
FastAPIがあっても設計の悪いAPIが良くなるわけではありません。適切な命名、バージョニング、エラーハンドリング、セキュリティ設計は依然必要です。FastAPIは「アイデア」から「定義されたAPI」への道筋をより確実にし、驚きの少ない開発を助けます。
FastAPIは、いくつかのコアアイデアを理解すれば扱いやすく感じられます。内部の詳細を暗記する必要はなく、日常的に使う要素を把握しておけば十分です。
フレームワークとは、ゼロから始めずにAPIを構築するためのツールと規約のセットです。FastAPIは、エンドポイント定義、入力の読み取り、出力の返却、エラー処理、コードの整理など、一般的なAPIタスクの「配線」を提供します。
ルーティングは、URLとHTTPメソッドをPythonの処理に結びつける仕組みです。
例えば、GET /usersを「ユーザー一覧」に、POST /usersを「ユーザー作成」に割り当てます。FastAPIでは通常、@app.get(...)や@app.post(...)のようなデコレータでルートを定義し、APIが何を提供するかを一目でわかるようにします。
すべてのAPI呼び出しはリクエスト(クライアントが送るもの)とレスポンス(サーバーが返すもの)で成り立っています。
FastAPIは次を助けます:
/users/{id})、クエリ文字列(?page=2)、ヘッダー、リクエストボディからデータを読み取る200, 201, 404など)で構造化されたJSONレスポンスを返すFastAPIはASGIというモダンなPythonウェブサーバー標準上で動作します。実務上は、FastAPIが多くの接続を効率的に扱えるよう設計されており、WebSocketのような長時間接続もサポートできる、ということを意味します。
Pythonの型ヒント(str, int, list[Item]など)は、FastAPIでは単なるドキュメントではなく重要な入力情報です。FastAPIはそれらを使って期待するデータを理解し、受信値を正しい型に変換し、より予測可能なAPIを作ります。
Pydanticモデルはデータの形(フィールド、型、オプション)を一箇所で定義する手段です。FastAPIはこれらのモデルを使って受信JSONを検証し、無効な入力を親切なエラーメッセージで拒否し、出力も一貫してシリアライズします。これにより、クライアントが不正なデータを送ってきてもAPIが安定して動作します。
FastAPIアプリはエンドポイント(URLパス+HTTPメソッド)を中心に構成されます。エンドポイントは「クライアントが何を要求するか」と「どのように要求するか」を表します。例:クライアントはGET /usersでユーザー一覧を取り、POST /usersで作成します。
パスはルート、メソッドはアクションです:
GET /products → データ取得POST /products → 作成用データを送信PUT /products/123 → 何かを置換/更新DELETE /products/123 → 削除FastAPIはURLの一部であるデータとオプションのフィルタを分けて扱います。
GET /users/42 → 42がユーザーID?以降に付くオプション。例:GET /users?limit=10&active=true → limitやactiveが結果の制御に使われるクライアントが構造化データ(通常はJSON)を送るとき、それはリクエストボディに入ります。多くの場合POSTやPUTで使います。
例:POST /ordersに { "item_id": 3, "quantity": 2 } のようなJSONを送る。
FastAPIは単純なPythonオブジェクト(辞書など)を返すこともできますが、レスポンスモデルを定義すると威力を発揮します。モデルは契約のように振る舞い、フィールドを常に整形し、不要な内部フィールドを除外し、型を保証します。その結果、クライアントは期待するレスポンスを把握しやすくなり、統合時のトラブルが減ります。
「Async(非同期)」は、多くの時間を待ちに費やすときにAPIが多数のリクエストを効率よく捌けるようにする方法です。
バリスタが注文をとる状況を想像してください。エスプレッソマシンが動いている間ずっと立ち止まって待っていたら、対応できる客数は少なくなります。より良い方法は、コーヒーを抽出している間に次の注文を受けることです。
Asyncはそれと同じ考え方です。FastAPIアプリはネットワーク待ちやデータベース呼び出しのような遅い処理を開始し、その待ち時間の間に他のリクエストを処理できます。
AsyncはI/O(待ち時間が多い処理)を多く含むAPIで特に有効です。例:
こうした処理が多い場合、asyncはスループットを改善し、負荷時にリクエストが滞留する可能性を減らします。
Asyncはすべてを高速化する魔法ではありません。エンドポイントが主にCPU負荷の高い処理(大きな画像のリサイズ、重いデータ処理、暗号化など)を行う場合、asyncはその計算自体を速めません。その場合は、バックグラウンドワーカー、プロセスプール、スケールアウトなど別の対策が必要です。
すべてを書き直す必要はありません。通常の同期defルート関数もFastAPIでそのまま動作します。多くのプロジェクトではシンプルなエンドポイントは同期のままにし、データベース呼び出しなどでasync defを使うことが一般的です。
バリデーションは外部から来たデータとあなたのコードの間にあるチェックポイントです。APIが入力(JSONボディ、クエリパラメータ、パスパラメータ)を受け取るとき、データが完全で正しい型で合理的な範囲内であることを確認したいはずです。これを行わずにDBに書き込んだり他サービスを呼び出すと問題が起きます。
FastAPIはPydanticモデルに依存しています。良いデータの形を一度だけ記述すると、FastAPIは自動で:
"42"→整数)クライアントが間違った形のデータを送ると、FastAPIは422 Unprocessable Entityと、どのフィールドにどんな問題があるかを指す構造化されたエラーを返します。これによりクライアント開発者は素早く不具合を直せます。
小さなモデルで必須フィールド、型、最小/最大制約、フォーマットを示します:
from pydantic import BaseModel, EmailStr, Field
class UserCreate(BaseModel):
email: EmailStr
age: int = Field(ge=13, le=120)
username: str = Field(min_length=3, max_length=20)
emailは必須ageは整数である必要があるageは13〜120の範囲EmailStrは有効なメール形式を要求同じモデルを出力に使えば、APIレスポンスが内部フィールドを漏らさず整った形で返されます。Pythonオブジェクトを返すと、FastAPI(Pydantic経由)が正しいフィールド名と型のJSONに変換します。
FastAPIの実用的な特徴の一つは、書いたコードに基づいてAPIドキュメントを自動生成してくれることです。
OpenAPIはAPIを構造化フォーマット(通常JSON)で記述する標準です。以下を明確にします:
GET /users/{id})機械可読なので、ツールはこれを使ってクライアント生成、リクエスト検証、チーム間の整合などを自動化できます。
FastAPIは2つの人間向けドキュメントページを自動で提供します:
通常、次のURLで利用できます:
/docs(Swagger UI)/redoc(ReDoc)パスパラメータ、リクエストモデル、レスポンスモデル、バリデーションルールを変更すると、OpenAPIスキーマ(とドキュメントページ)は自動で更新されます。別途ドキュメントをメンテする手間が減ります。
FastAPIアプリは小さくても「本物」の感触があります。Pythonオブジェクトappを定義し、いくつかのルートを追加し、ローカルサーバーでブラウザから試せます。
最小の実用例はこちら:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "Hello, FastAPI"}
これだけで、GET /がJSONを返す一つのルートができます。
学習用として、リストにアイテムを保存する例です。これはDBではなく、サーバー再起動でデータは消えますが学習には十分です。
from fastapi import FastAPI
app = FastAPI()
items = []
@app.post("/items")
def create_item(name: str):
item = {"id": len(items) + 1, "name": name}
items.append(item)
item
():
items
POST /items?name=Coffee でアイテムを追加GET /items でリストを取得一般的なスターター構成:
main.py(appとルートを作成)requirements.txt または pyproject.toml(依存関係)通常の流れ:
uvicorn main:app --reload)http://127.0.0.1:8000を開いてエンドポイントを試すFastAPIの「依存関係」は、エンドポイントが必要とする共通の入力(DBセッション、現在のログインユーザー、アプリ設定、共通クエリパラメータなど)を表します。これらを各ルートで手動で生成/解析する代わりに一度定義しておけば、FastAPIが必要な場所へ提供してくれます。
依存関係は通常、値を返す関数(またはクラス)です。FastAPIはその関数を呼び出し、必要なパラメータを見て結果をエンドポイントに注入します。
依存性注入と呼ばれますが、「必要なものを宣言すればFastAPIが配線してくれる」と考えるとわかりやすいです。
依存関係がなければ、各エンドポイントで:
といったことが起きます。依存関係を使えばロジックを一箇所にまとめられ、後でDBセッションの作り方やユーザーロード方法を変更する際も一箇所直せば済みます。
page/limitの解析と検証を再利用よく見るパターンの概念例:
from fastapi import Depends, FastAPI
app = FastAPI()
def get_settings():
return {"items_per_page": 20}
@app.get("/items")
def list_items(settings=Depends(get_settings)):
return {"limit": settings["items_per_page"]}
Depends(...)で依存関係を宣言すると、FastAPIがその結果をエンドポイントのパラメータとして渡します。get_db()やget_current_user()のような複雑な部品にも同じ方法が使え、アプリが成長してもコードが綺麗に保てます。
FastAPIはAPIを自動的に保護するわけではありません。方式を選び、依存関係などでエンドポイントに組み込む必要があります。良い点は、FastAPIが依存関係システムを通じて一般的なセキュリティパターンを簡単に実装できるビルディングブロックを提供していることです。
**認証(Authentication)**は「あなたは誰か?」に答え、**認可(Authorization)**は「何ができるか?」に答えます。
例:ユーザーは認証されていても、管理者専用ルートへのアクセスは認可されないかもしれません。
X-API-Key)で送る。ローテーションや取り消しを管理すること。FastAPIはfastapi.securityのようなユーティリティを提供し、OpenAPIにもこれらをドキュメント化できます。
ユーザーパスワードを保存する場合、平文で保存してはいけません。ソルト付きの遅いハッシュ(bcryptやargon2などの既存ライブラリ)を使いましょう。さらにレート制限やアカウントロックアウト方針も検討してください。
セキュリティは細部の問題です:トークンの保存、CORS設定、HTTPS、シークレット管理、機微なエンドポイントでの正しい認可チェックなど。組み込みのヘルパーは出発点として使い、運用前にレビューとテストで設計を検証してください。
テストは「自分のマシンでは動く」から「安心して公開できる」へ変える工程です。良い知らせは:FastAPIはStarlette上に構築されているため、強力なテストツールがほとんど追加設定なしで使えることです。
単体テストは小さな部品(値を計算する関数、現在のユーザーを読み込む依存関係、DBを呼ぶサービスメソッドなど)に焦点を当てます(外部はモックすることが多い)。
統合テストはAPIをエンドツーエンドで検証します:エンドポイントを呼び出してHTTPレスポンスを検証することで、ルーティングや依存関係の配線、バリデーションの問題を発見できます。
健全なテストスイートは、速い単体テストを多く、信頼度の高い統合テストを少なめに持つことが多いです。
FastAPIアプリはStarletteのTestClientを使ってプロセス内でテストできます。サーバーを起動する必要はありません。
from fastapi.testclient import TestClient
from app.main import app
client = TestClient(app)
def test_healthcheck():
r = client.get("/health")
assert r.status_code == 200
予測できるデータを使い、外部サービスはモックするかテスト用DBを使い、テスト間で状態を共有しないようにします。速いテストは実行され、遅いテストは省かれがちです。
FastAPIアプリを公開するには、適切なランナーを選び、本番向けにいくつかの必須要素を追加するだけです。
ローカルでuvicorn main:app --reloadを使うと開発用の設定(自動リロードや詳細なエラー表示など)で動きます。本番では通常、Uvicornを--reloadなしで動かし、プロセスマネージャ(Gunicorn+Uvicornワーカー等)やリバースプロキシの背後で運用します。目的は安定性:再起動の管理、予測可能なパフォーマンス、安全なデフォルト設定です。
一般的なパターン:
これにより1つのコードベースを複数環境にデプロイできます。
本番と呼ぶ前に確認する項目:
/healthのような監視用エンドポイントローカルから本番へ移すときは、OpenAPI出力をCIで使ってクライアント生成やリクエスト検証を行うなど、API契約を標準化すると良いです。例えば、Koder.aiのようなツールを使えばチャットでAPIを設計し、エンドポイントやモデルのスキャフォールドを素早く生成して標準的なレビュー・デプロイパイプラインへ繋げることもできます。
FastAPIは、PythonでクリーンでモダンなREST APIを構築したいときに強力な選択肢です。特にリクエスト/レスポンスモデルの明確さや、APIが成長したときの予測可能性を重視する場合に適しています。
FastAPIが常に最短の選択とは限りません:
FastAPIは実運用で非常に高速になり得ますが、速度はDB呼び出し、ネットワーク待ち、ビジネスロジック次第です。フレームワークだけで「遅いI/O」や「非効率なクエリ」を解決するわけではないことに注意してください。
FastAPIが合いそうなら、ルーティングパターン、Pydanticモデル、データベース統合、バックグラウンドタスク、基本的な認証から始めてください。実践的な進め方は小さなエンドポイントセットを作り、再利用可能な依存関係とテストを追加しながら拡張することです。初期のスキャフォールド(ルート、モデル、デプロイ準備構造)を素早く作りたい場合は、チャットで仕様を詰めてコードを生成するワークフロー(vibe-coding)を使うのも有効です。Koder.aiのようなツールはこの段階で役立ちます:チャットでAPIをプロトタイプし、生成されたコードをレビューして標準的なプロジェクトとして出力できます。
FastAPIは、ボイラープレートを最小限に抑えてAPIを構築できるPythonのウェブフレームワークです。エンドポイント関数(例:@app.get("/users"))を書くと、FastAPIがルーティング、リクエスト解析、バリデーション、JSONレスポンスなどを処理します。
大きな利点は、型ヒントやPydanticモデルがAPIが受け取るものと返すものの明確な契約として機能する点です。
APIは、他のソフトウェアがデータをやり取りするために呼び出すURL(エンドポイント)の集合です。
例えば、クライアントがGET /weather?city=Berlinを要求すると、サーバーは構造化されたJSONで応答します。クライアントはサーバーのデータベースに直接アクセスする必要はなく、APIの応答を使って表示を行います。
ルーティングはHTTPメソッドとパスをPython関数に結びつけます。
FastAPIでは通常、デコレータを使います:
@app.get("/items") は読み取り操作向け@app.post("/items") は作成操作向け@app.put("/items/{id}") は更新/置換向け@app.delete("/items/{id}") は削除向けこのようにコードからAPIの表面(どんなエンドポイントがあるか)を一目で把握できます。
パスパラメータはURLの一部で、特定のリソースを識別するために使われ、通常は必須です。
GET /users/42 → 42 はパスパラメータです。クエリパラメータは?の後に付加されるもので、通常はオプションのフィルタや制御に使われます。
Pydanticモデルはデータの形(フィールド、型、オプション)を定義します。FastAPIはこれを用いて:
"42"→整数)バリデーションに失敗すると、FastAPIは通常422 Unprocessable Entityで、どのフィールドが間違っているかを示す詳細なエラーを返します。
FastAPIはエンドポイントや型ヒント、モデルからOpenAPIスキーマを自動生成します。
通常、次のようなインタラクティブなドキュメントが自動で利用できます:
/docs(Swagger UI)/redoc(ReDoc)コードからスキーマが派生するため、パラメータやモデルを変更するとドキュメントも自動的に更新されます。
async defはI/O待ちが多い処理(データベース呼び出し、外部HTTPリクエスト、ファイルやオブジェクトストレージへの入出力)で有効です。
次の場合は通常def(同期関数)で問題ありません:
同じアプリ内で同期と非同期を混在させるのはよくあるパターンです。
依存性(Dependencies)は、Depends()を通じてエンドポイントに注入される再利用可能な『部品』です。
よくある用途:
重複を減らし、横断的なロジックを一箇所に集中させることで、変更があっても1箇所を直せば済みます。
FastAPI自体は自動でセキュリティを提供しないので、方式を選んで各エンドポイントに適用します。
一般的なパターン:
注意点:
テストにはStarletteのTestClientを使ってアプリに対してプロセス内リクエストを行う方法が便利です(サーバーを立てる必要がありません)。
アサーションの例:
デプロイ時はASGIサーバー(Uvicorn等)で稼働させ、ログ、ヘルスチェック、タイムアウト、環境変数による設定などの本番向けチェックを追加します。
GET /users?limit=10&active=true → limitやactiveがクエリパラメータです。