FastAPIでは、Pythonの型ヒントがAPIの入力仕様を表します。
型を適切に書けば、受け取った値の変換と検証、エディターによる補完、APIドキュメントの生成を一つの定義から進められます。
ただし、Pythonの型ヒントとFastAPIの入力検証は同じ機能ではありません。
型ヒントはPython単体では実行時の型を強制せず、FastAPIとPydanticがその情報を利用してリクエストを処理します。
FastAPIの全体像を先に確認したい場合は、FastAPIの特徴と基本的な実装例も参考になります。
Pythonの型ヒントが表すもの
型ヒントとは、変数、引数、戻り値に想定する型を書き添える仕組みです。
たとえば、次の関数は名前に文字列、年齢に整数を受け取り、文字列を返すことを示しています。
def greet(name: str, age: int) -> str:
return f"{name}さんは{age}歳です。"
この記述は、コードを読む人に値の形を伝え、エディターや静的型チェックツールが不整合を見つける手がかりになります。
一方で、通常のPython関数は型ヒントだけで引数を自動検証しません。
パスパラメータとクエリパラメータの型指定
パスパラメータはURLの経路に埋め込まれる値です。
クエリパラメータは、URLの末尾に?q=bookのように付ける値です。
FastAPIはルートの定義と関数の引数を照合し、それぞれの値をどこから受け取るか判断します。
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str | None = None):
return {"item_id": item_id, "q": q}
item_idはルートに含まれるため、パスパラメータとして扱われます。item_id: intにより、FastAPIはURLから受け取った値を整数として解釈し、変換できるか検証します。qはルートに含まれないため、クエリパラメータとして扱われます。q: str | None = Noneは、文字列またはNoneを許可し、省略時の値をNoneにします。
たとえば、/items/10?q=bookでは、関数内のitem_idは整数の10になり、qは文字列のbookになります。
/items/abcのように整数へ変換できない値を送ると、FastAPIの既定の処理では検証エラーとしてHTTP 422が返ります。
ここでいうバリデーションは、受け取った値が定義した型や条件に合うか確認する処理です。
型変換に成功したことと、業務上正しい値であることは別なので、必要に応じて値の範囲や独自ルールも定義します。
Pydanticモデルでリクエストボディを定義する
JSONのように複数の項目を持つリクエストボディには、PydanticのBaseModelを使います。
モデルに項目名、型、初期値を書くと、データ構造と検証規則をまとめて表せます。
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
price: float
is_offer: bool | None = None
app = FastAPI()
@app.put("/items/{item_id}")
def update_item(item_id: int, item: Item):
return {"item_id": item_id, **item.model_dump()}
nameとpriceには初期値がないため、リクエストで必要な項目です。
is_offerはboolまたはNoneを受け取り、省略された場合はNoneになります。
FastAPIは受け取った本文をItemとして検証し、必要な項目の不足や型の不整合があれば、既定ではHTTP 422でエラーの場所と内容を返します。
model_dump()は、検証済みのPydanticモデルをPythonの辞書として取り出すメソッドです。
リクエストとレスポンスのモデルを続けて学ぶ場合は、FastAPIとPydanticによるリクエスト・レスポンス定義も参照してください。
型情報が担う役割
| 仕組み | 主な役割 |
|---|---|
| Pythonの型ヒント | 想定する型をコードに残し、エディターの補完や静的型チェックに利用する |
| FastAPI | パス、クエリ、リクエストボディを識別し、値の変換と検証に型情報を使う |
| Pydanticモデル | 複数項目の構造、初期値、フィールドごとの検証条件を定義する |
| OpenAPIドキュメント | エンドポイントの入力と出力を機械可読な仕様として表し、対話型ドキュメントに反映する |
この分担を理解すると、「型ヒントを書けばPythonがすべての値を拒否してくれる」という誤解を避けられます。
通常のPythonコードに対する静的な確認と、FastAPIがリクエスト時に行う検証を分けて考えることが必要です。
リスト、辞書、Unionを現代的な構文で書く
Python 3.10以降の構文では、リストや辞書、複数候補の型を次のように簡潔に書けます。
def calculate_totals(
item_ids: list[int],
prices: dict[str, float],
) -> list[float]:
return [prices[str(item_id)] for item_id in item_ids]
value: int | str = 42
name: str | None = None
list[int]は整数を要素に持つリストを表します。dict[str, float]は文字列のキーと浮動小数点数の値を持つ辞書を表します。int | strは整数または文字列を受け取れることを表します。str | Noneは文字列に加えてNoneも許可することを表します。
str | Noneと書くだけでは、「引数や項目を省略できる」とは限りません。
省略を許可するには、関数の引数やPydanticモデルで= Noneのような初期値も設定します。
厳格な型とカスタムバリデーション
Pydanticは、入力を定義した型へ変換できる場合に受け付けることがあります。
変換を許さず、文字列を文字列として受け取りたい項目には、StrictStrのような厳格な型を使えます。
型だけでは表せない条件は、@field_validatorで検証します。
次の例では、商品名に厳格な文字列型を使い、価格が正の数であることを確認しています。
from pydantic import BaseModel, StrictStr, field_validator
class Product(BaseModel):
title: StrictStr
price: float
@field_validator("price")
@classmethod
def price_must_be_positive(cls, value: float) -> float:
if value <= 0:
raise ValueError("価格は正の数でなければなりません")
return value
カスタムバリデーターは、条件を満たさないときにValueErrorを送出し、条件を満たすときは検証した値を返します。
すべての項目を厳格にするのではなく、変換を許すかどうかをAPIの利用者と合意して決めると、意図しない拒否を避けられます。
型指定を導入する手順
- パスとクエリの型を書く:まず
int、str、boolなどの基本型を指定します。 - リクエストボディをモデルにする:複数項目を受け取る処理は
BaseModelへまとめます。 - 省略と
Noneを区別する:許可する型と初期値を別々に確認します。 - 業務条件を追加する:正数や文字数など、型だけでは表せない条件にフィールド制約やバリデーターを使います。
- 正常系とエラーを試す:対話型APIドキュメントとテストコードで、変換後の値、HTTPステータス、エラー内容を確認します。
- 静的型チェックを併用する:エディターや型チェックツールで、リクエストを受け取った後のコードも点検します。
初心者が混同しやすい点
型ヒントだけで実行時検証が行われるわけではない
通常のPython関数では、型ヒントは値を自動で拒否しません。
FastAPIでは、フレームワークとPydanticが型情報を読み取り、HTTPリクエストに対する実行時検証を行います。
Noneを許すことと省略できることは別である
str | Noneは値としてNoneを許す指定です。
省略時の動作は= Noneなどの初期値によって決まるため、型と初期値を一組で確認します。
型の変換と業務ルールの検証は分けて考える
floatとして解釈できることだけでは、価格として妥当だとは判断できません。
正の数であることなど、アプリケーション固有の条件はフィールド制約やカスタムバリデーターで補います。
FastAPIの型指定を使い始める要点
最初は、パスとクエリに基本型を付け、リクエストボディをPydanticモデルで表すところから始めます。
次に、省略可能な値、リストや辞書、厳格な型、独自の検証条件へ進むと、各指定の役割を切り分けて理解できます。
型指定は入力検証だけの仕組みではありません。
コード、API仕様、テストで同じデータ構造を共有し、変更時の見落としを減らすための土台になります。
この記事に関連する株式会社greedenの取り組み
FastAPIの型指定は、入力ミスを早期に見つけ、APIの仕様をチームで共有する土台になります。
株式会社greedenは、FastAPIを含むWebシステム開発で、要件整理からAPI開発、テスト、保守と改善まで支援しています。
