はじめに
FastAPIとは
FastAPIは、Python 3.7以降で動作する高速なWebフレームワークです。RESTful APIの開発に特化しており、型ヒントを活用することで開発者体験を大きく向上させています。
なぜFastAPIが選ばれるのか
FastAPIが多くの開発者に選ばれる理由は以下の通りです。
- 高速な実行速度: NodeJSやGoと同等のパフォーマンスを実現
- 自動ドキュメント生成: コードから自動的にAPIドキュメントが生成される
- 型安全性: Pythonの型ヒントによる自動バリデーション
- 直感的な記述: シンプルで分かりやすいコード
この記事で学べること
この記事では、FastAPIの基本的な機能を一通り体験できます。環境構築から始めて、実際にAPIを作成し、パラメータやリクエストボディの扱い方を学びます。
環境構築
必要な環境
- Python 3.7以降
- pip(Pythonのパッケージ管理ツール)
FastAPIのインストール
FastAPIとASGIサーバーのuvicornをインストールします。
pip install fastapi uvicorn[standard]
uvicornは、FastAPIアプリケーションを実行するためのASGIサーバーです。[standard]オプションを付けることで、本番運用に適した依存関係も一緒にインストールされます。
開発に便利なツール
FastAPIは自動でAPIドキュメントを生成してくれるため、特別なツールは不要です。ブラウザだけでAPIのテストができますね。
最小構成のAPIを作成
Hello World API
まずは最もシンプルなAPIを作成してみましょう。main.pyというファイルを作成します。
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"message": "Hello World"}
このコードは以下のような構造になっています。
-
FastAPI()でアプリケーションのインスタンスを作成 -
@app.get("/")でGETリクエストのエンドポイントを定義 - 関数が返す辞書が自動的にJSONに変換される
サーバーの起動方法
以下のコマンドでサーバーを起動します。
uvicorn main:app --reload
-
main: ファイル名(main.py) -
app: FastAPIインスタンスの変数名 -
--reload: ファイルの変更を検知して自動的に再起動
起動後、http://127.0.0.1:8000にアクセスすると、先ほど定義したレスポンスが返ってきます。
自動生成されるAPIドキュメント
FastAPIの大きな特徴の一つが、自動生成されるAPIドキュメントです。
-
http://127.0.0.1:8000/docs: Swagger UIによる対話的なドキュメント -
http://127.0.0.1:8000/redoc: ReDocによる読みやすいドキュメント
これらのページでは、APIの仕様を確認したり、実際にリクエストを送信してテストしたりできます。
パスパラメータとクエリパラメータ
パスパラメータの使い方
URLの一部を変数として受け取る方法です。
@app.get("/items/{item_id}")
def read_item(item_id: int):
return {"item_id": item_id}
{item_id}の部分がパスパラメータになります。型ヒントintを指定することで、自動的に整数への変換とバリデーションが行われますね。
例えば、/items/42にアクセスすると{"item_id": 42}が返ります。文字列を指定すると自動的にエラーが返されます。
クエリパラメータの使い方
URLの?以降に指定するパラメータです。
@app.get("/items/")
def read_items(skip: int = 0, limit: int = 10):
return {"skip": skip, "limit": limit}
関数の引数として定義するだけで、クエリパラメータとして扱われます。デフォルト値を指定することで、省略可能なパラメータになります。
/items/?skip=5&limit=20のようにアクセスできます。
型ヒントによる自動バリデーション
型ヒントを指定するだけで、FastAPIが自動的にバリデーションを行ってくれます。不正な値が渡された場合は、詳細なエラーメッセージと共に422ステータスコードが返されます。
リクエストボディの扱い
Pydanticモデルの定義
POSTリクエストなどでデータを受け取る場合、Pydanticモデルを使用します。
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
Pydanticモデルは、データの構造と型を定義するためのクラスです。デフォルト値を指定することで、省略可能なフィールドを定義できます。
POSTリクエストの処理
@app.post("/items/")
def create_item(item: Item):
return {"item": item, "total": item.price + (item.tax or 0)}
関数の引数としてItem型を指定するだけで、リクエストボディが自動的にPydanticモデルに変換されます。バリデーションも自動的に行われますね。
以下のようなJSONをPOSTできます。
{
"name": "商品A",
"description": "素晴らしい商品です",
"price": 1000.0,
"tax": 100.0
}
レスポンスモデルの指定
レスポンスの形式も定義できます。
class ItemResponse(BaseModel):
name: str
price: float
total: float
@app.post("/items/", response_model=ItemResponse)
def create_item(item: Item):
total = item.price + (item.tax or 0)
return {"name": item.name, "price": item.price, "total": total}
response_modelを指定することで、レスポンスの型安全性が保証され、ドキュメントにも反映されます。
HTTPステータスコードとレスポンス
ステータスコードの設定
デフォルトでは200が返されますが、明示的に指定することもできます。
from fastapi import status
@app.post("/items/", status_code=status.HTTP_201_CREATED)
def create_item(item: Item):
return item
statusモジュールを使うことで、分かりやすい定数名でステータスコードを指定できますね。
エラーハンドリング
エラーを返す場合はHTTPExceptionを使用します。
from fastapi import HTTPException
@app.get("/items/{item_id}")
def read_item(item_id: int):
if item_id > 100:
raise HTTPException(
status_code=404,
detail="Item not found"
)
return {"item_id": item_id}
カスタムレスポンスの返し方
JSONだけでなく、様々な形式のレスポンスを返せます。
from fastapi.responses import HTMLResponse
@app.get("/html", response_class=HTMLResponse)
def get_html():
return """
<html>
<body>
<h1>Hello FastAPI</h1>
</body>
</html>
"""
response_classを指定することで、HTMLやプレーンテキストなど、JSON以外の形式も返せます。
まとめ
FastAPIの主な特徴
この記事で見てきたように、FastAPIには以下のような特徴があります。
- 型ヒントによる自動バリデーションとドキュメント生成
- シンプルで直感的なコード記述
- 高速な実行パフォーマンス
- 豊富な機能が標準で提供されている