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を使ってデータ検証を行います:
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開発を始める方に、強くお勧めします。

