FastAPIは、Pythonで高速で現代的なREST APIを構築するためのフレームワークです。本記事では、FastAPIの基礎から実装まで、初心者でもわかりやすく解説していきますね。Djangoなどの重いフレームワークではなく、シンプルで高性能なAPI開発を始めたい方は必見です。
FastAPIとは
FastAPIは、Starlette(ウェブフレームワーク)とPydantic(データ検証ライブラリ)をベースにした、2018年に登場した比較的新しいフレームワークだと思います。以下のような特徴があります:
- 高速:Node.jsやGoと同等のパフォーマンスを実現してくれます
- 簡単:シンプルで直感的な記法で素早く開発可能です
- 自動ドキュメント生成:SwaggerUIやReDocで自動的にAPI仕様書を作成
- 型ヒント対応:Python 3.6+の型注釈を活用した安全なコードが書けます
- 非同期対応:async/awaitでスケーラブルなAPI構築が可能
環境構築と基本インストール
まず、FastAPIをインストールしましょう。pipコマンドで簡単にセットアップできます:
pip install fastapi uvicorn
uvicornはASGIサーバーで、FastAPIアプリケーションを実行するために必要だと思います。その他の推奨パッケージもインストールしておくと良いですね:
pip install python-multipart pydantic
最初のFastAPIアプリケーション
では、シンプルなREST APIを作成してみましょう。以下は「Hello World」レベルのサンプルコードですが、ここから実際のプロジェクトへの応用が見えてくると思います:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello, FastAPI!"}
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}
このコードをmain.pyという名前で保存し、以下のコマンドで実行します:
uvicorn main:app --reload
ブラウザでhttp://127.0.0.1:8000にアクセスすると、APIが動作しているのを確認できます。--reloadオプションを付けると、ファイル変更時に自動的に再起動されるため、開発効率がグンと向上しますね。
リクエストボディとPydanticモデル
実践的なAPIには、クライアントからのリクエストボディの処理が欠かせません。FastAPIではPydanticを使ってデータ検証を行います。最初、僕がハマったのはここで、JSONデータをどう型安全に扱うかということなんです:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
description: str = None
tax: float = None
@app.post("/items/")
async def create_item(item: Item):
return item
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
return {"item_id": item_id, "item": item}
ItemというPydanticモデルを定義することで、自動的に以下の処理が実行されるようになります:
- リクエストボディのJSON形式を
Itemインスタンスに変換 - 型チェック(例:
priceは必ずfloat型である必要がある) - 必須項目と任意項目の区別(
=Noneで任意になります) - 自動的にSwaggerドキュメントに反映される
自動ドキュメント生成
FastAPIの最大の特徴の一つが、自動的にAPI仕様書を生成する機能です。アプリケーション実行中に以下のURLにアクセスしてみてください:
http://127.0.0.1:8000/docs– Swagger UIでインタラクティブなドキュメントhttp://127.0.0.1:8000/redoc– ReDocで読みやすいドキュメント
これらのドキュメントは、コード内の型注釈とdocstringから自動生成されます。追加の設定を記述する必要がなく、コード自体がドキュメントになるというのは、開発効率を大きく向上させるんですよね。
クエリパラメータとパスパラメータ
REST APIでは、URLからのデータ取得パターンが複数あります。それぞれを実装してみましょう。現場ではこれらの使い分けが実は地味に重要です:
from fastapi import FastAPI
from typing import Optional
app = FastAPI()
# パスパラメータ
@app.get("/users/{user_id}")
async def get_user(user_id: int):
return {"user_id": user_id}
# クエリパラメータ
@app.get("/search/")
async def search(q: str, skip: int = 0, limit: int = 10):
return {"query": q, "skip": skip, "limit": limit}
# 複合パラメータ
@app.get("/products/{category}/")
async def get_products(category: str, skip: int = 0, limit: int = 20, on_sale: Optional[bool] = None):
return {
"category": category,
"skip": skip,
"limit": limit,
"on_sale": on_sale
}
on_sale=Noneとすることで、パラメータはオプショナルになります。型注釈により、自動的に型チェックが行われるため、バグを未然に防げるんです。
HTTPメソッドとステータスコード
REST APIでは、適切なHTTPメソッドとステータスコードの使い分けが重要です。調べてみたら、FastAPIでは本当に簡単に実装できることに驚きました:
from fastapi import FastAPI, status
from pydantic import BaseModel
from typing import Optional
app = FastAPI()
class Item(BaseModel):
name: str
price: float
# GET - リソース取得
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id, "name": "Sample Item"}
# POST - リソース作成
@app.post("/items/", status_code=status.HTTP_201_CREATED)
async def create_item(item: Item):
return {"message": "Item created", "item": item}
# PUT - リソース更新(置換)
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
return {"item_id": item_id, "item": item}
# DELETE - リソース削除
@app.delete("/items/{item_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_item(item_id: int):
return None
status_codeパラメータで、レスポンスのHTTPステータスコードを指定できます。201 Createdや204 No Contentなど、RESTful APIの慣例に従った実装が可能だと思います。
エラーハンドリング
堅牢なAPIには、適切なエラーハンドリングが必須です。FastAPIではHTTPExceptionを使ってシンプルに実装できるんですね:
from fastapi import FastAPI, HTTPException
app = FastAPI()
# ダミーデータベース
items_db = {
1: {"id": 1, "name": "Item 1"},
2: {"id": 2, "name": "Item 2"}
}
@app.get("/items/{item_id}")
async def read_item(item_id: int):
if item_id not in items_db:
raise HTTPException(
status_code=404,
detail="Item not found"
)
return items_db[item_id]
@app.delete("/items/{item_id}")
async def delete_item(item_id: int):
if item_id not in items_db:
raise HTTPException(
status_code=404,
detail="Item not found"
)
del items_db[item_id]
return {"message": "Item deleted"}
HTTPExceptionを発生させると、FastAPIが自動的に適切なエラーレスポンスをJSON形式で返してくれます。公式ドキュメントによると、これによって一貫性のあるエラー処理が実現できるんです。
非同期処理の活用
FastAPIは非同期処理に対応しており、async/awaitを使うことでスケーラブルなAPIを構築できます。本番環境での処理速度が大きく変わる部分ですね:
import asyncio
from fastapi import FastAPI
app = FastAPI()
@app.get("/slow-item/{item_id}")
async def read_slow_item(item_id: int):
# 外部APIの呼び出しなど、時間がかかる処理をシミュレート
await asyncio.sleep(2)
return {"item_id": item_id, "processed": True}
@app.get("/fast-items/")
async def read_fast_items():
# 複数の非同期操作を並列実行
results = await asyncio.gather(
asyncio.sleep(1),
asyncio.sleep(1)
)
return {"message": "All items fetched", "time": "~1 second"}
非同期処理により、複数のリクエストを効率的に処理でき、APIのパフォーマンスが大幅に向上します。
CORSの設定
ブラウザからのクロスオリジンリクエストに対応する場合、CORS(Cross-Origin Resource Sharing)の設定が必要になります。最初、ここでハマった経験があります:
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 本番環境では具体的なドメインを指定
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/items/")
async def read_items():
return [{"id": 1, "name": "Item 1"}]
allow_originsに["*"]を指定すると全て許可されますが、セキュリティ上、本番環境では具体的なドメインを指定する必要があります。開発段階では便利ですが、運用時には気をつけましょう。
まとめ
FastAPIを使うことで、Pythonで高速で現代的なREST APIを簡単に構築できるんですね。主なポイントは以下の通りです:
- セットアップが簡単:FastAPIとuvicornをインストールするだけで開始可能
- 型ヒント対応:Python 3.6+の型注釈で自動的に検証とドキュメント生成
- 自動ドキュメント生成:Swagger UIとReDocで/docsと/redocにアクセス
- Pydanticモデル:リクエストボディの検証と変換が自動的に実行される
- 非同期対応:async/awaitでスケーラブルなAPI開発が可能
- エラーハンドリング:HTTPExceptionで簡潔にエラー処理を実装
- CORS対応:ミドルウェアで容易にクロスオリジン設定が可能
FastAPIは学習曲線が緩く、同時に本番環境で使用可能な高性能なフレームワークだと思います。今からPythonでREST API開発を始める方に、強くお勧めします。
よくある質問(FAQ)
FastAPIはDjangoと比べてどう違うのですか?
FastAPIはAPI開発に特化した軽量フレームワークで、Django(フルスタックフレームワーク)とは設計思想が異なります。FastAPIの方がAPI開発の開発速度が速く、パフォーマンスも優れていますね。DjangoはテンプレートエンジンやAdmin画面など、Web全般に対応しているため、より大規模なプロジェクト向けと言えます。
非同期処理(async/await)は必須ですか?
必須ではありませんが、推奨されています。非同期処理を使うことで、I/O待機中に他のリクエストを処理できるため、スケーラビリティが向上します。同期的な関数でも動作しますが、本番環境ではasync/awaitの使用が現場での標準になってきていると思います。
PydanticモデルなしでAPI開発できますか?
技術的には可能ですが、Pydanticを使わないことは強く非推奨です。Pydanticを使うことで、型チェック、自動ドキュメント生成、バリデーションなどが自動的に実現されます。調べてみたら、これらの機能を手動で実装すると、かなりの手間と複雑さが増すことがわかりました。
本番環境でのデプロイはどう行うのですか?
FastAPIアプリケーションはuvicornで実行されますが、本番環境ではGunicornやNginxとの組み合わせが一般的です。公式ドキュメントによると、Dockerコンテナ化して、クラウドプラットフォーム(AWS、GCP、Heroku等)にデプロイするのが標準的なアプローチになっています。
データベースはどう接続するのですか?
FastAPI自体はデータベース機能を持たないため、SQLAlchemy、Tortoise ORM、Mongoengineなどのライブラリを別途使用します。SQLAlchemyはSQL系データベース、Tortoise ORMは非同期対応が特徴です。どのORMを選ぶかは、プロジェクトの要件によって判断することになりますね。

