リクエストボディ¶
🌐 Translation by AI and humans
This translation was made by AI guided by humans. 🤝
It could have mistakes of misunderstanding the original meaning, or looking unnatural, etc. 🤖
You can improve this translation by helping us guide the AI LLM better.
クライアント(例えばブラウザ)からAPIにデータを送信する必要がある場合、リクエストボディとして送信します。
リクエストボディは、クライアントからAPIへ送信されるデータです。レスポンスボディは、APIがクライアントに送信するデータです。
APIはほとんどの場合 レスポンス ボディを送信する必要があります。しかしクライアントは、常に リクエストボディ を送信する必要があるとは限りません。場合によっては、クエリパラメータ付きのパスだけをリクエストして、ボディを送信しないこともあります。
リクエストボディを宣言するには、Pydantic モデルを使用し、その強力な機能とメリットをすべて利用します。
情報
データを送信するには、POST(より一般的)、PUT、DELETE、PATCH のいずれかを使用すべきです。
GET リクエストでボディを送信することは仕様上は未定義の動作ですが、それでもFastAPIではサポートされています。ただし、非常に複雑/極端なユースケースのためだけです。
推奨されないため、Swagger UIによる対話的ドキュメントでは GET 使用時のボディのドキュメントは表示されず、途中のプロキシが対応していない可能性もあります。
Pydanticの BaseModel をインポート¶
まず、pydantic から BaseModel をインポートする必要があります:
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
🤓 Other versions and variants
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
データモデルの作成¶
次に、BaseModel を継承するクラスとしてデータモデルを宣言します。
すべての属性に標準のPython型を使用します:
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
🤓 Other versions and variants
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
クエリパラメータの宣言と同様に、モデル属性がデフォルト値を持つ場合は必須ではありません。そうでなければ必須です。単にオプションにするには None を使用してください。
例えば、上記のモデルは次のようなJSON「object」(またはPythonの dict)を宣言します:
{
"name": "Foo",
"description": "An optional description",
"price": 45.2,
"tax": 3.5
}
...description と tax はオプション(デフォルト値が None)なので、このJSON「object」も有効です:
{
"name": "Foo",
"price": 45.2
}
パラメータとして宣言¶
path operation に追加するには、パスパラメータやクエリパラメータを宣言したのと同じ方法で宣言します:
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
🤓 Other versions and variants
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
...そして、作成したモデル Item を型として宣言します。
結果¶
そのPythonの型宣言だけで FastAPI は以下を行います:
- リクエストのボディをJSONとして読み取ります。
- 対応する型に変換します(必要な場合)。
- データを検証します。
- データが無効な場合は、どこで何が不正なデータだったのかを正確に示す、分かりやすい明確なエラーを返します。
- 受け取ったデータをパラメータ
itemに渡します。- 関数内で
Item型として宣言したため、すべての属性とその型について、エディタサポート(補完など)も利用できます。
- 関数内で
- モデル向けの JSON Schema 定義を生成します。プロジェクトにとって意味があるなら、他の場所でも好きなように利用できます。
- それらのスキーマは生成されるOpenAPIスキーマの一部となり、自動ドキュメントの UIs で使用されます。
自動ドキュメント¶
モデルのJSON Schemaは、OpenAPIで生成されたスキーマの一部になり、対話的なAPIドキュメントに表示されます:

また、それらが必要な各 path operation 内のAPIドキュメントでも使用されます:

エディタサポート¶
エディタ上で、関数内のあらゆる場所で型ヒントと補完が得られます(Pydanticモデルの代わりに dict を受け取った場合は起きません):

不正な型操作に対するエラーチェックも得られます:

これは偶然ではなく、フレームワーク全体がその設計を中心に構築されています。
そして、すべてのエディタで動作することを確実にするために、実装前の設計フェーズで徹底的にテストされました。
これをサポートするために、Pydantic自体にもいくつかの変更が加えられました。
前述のスクリーンショットは Visual Studio Code で撮影されたものです。
ただし、PyCharm や、他のほとんどのPythonエディタでも同じエディタサポートを得られます:

豆知識
エディタとして PyCharm を使用している場合、Pydantic PyCharm Plugin を使用できます。
以下により、Pydanticモデルに対するエディタサポートが改善されます:
- auto-completion
- type checks
- refactoring
- searching
- inspections
モデルを使用する¶
関数内では、モデルオブジェクトのすべての属性に直接アクセスできます:
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
item_dict = item.model_dump()
if item.tax is not None:
price_with_tax = item.price + item.tax
item_dict.update({"price_with_tax": price_with_tax})
return item_dict
🤓 Other versions and variants
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
item_dict = item.model_dump()
if item.tax is not None:
price_with_tax = item.price + item.tax
item_dict.update({"price_with_tax": price_with_tax})
return item_dict
リクエストボディ + パスパラメータ¶
パスパラメータとリクエストボディを同時に宣言できます。
FastAPI は、パスパラメータに一致する関数パラメータは パスから取得 し、Pydanticモデルとして宣言された関数パラメータは リクエストボディから取得 すべきだと認識します。
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
return {"item_id": item_id, **item.model_dump()}
🤓 Other versions and variants
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
return {"item_id": item_id, **item.model_dump()}
リクエストボディ + パス + クエリパラメータ¶
body、path、query パラメータもすべて同時に宣言できます。
FastAPI はそれぞれを認識し、正しい場所からデータを取得します。
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
app = FastAPI()
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, q: str | None = None):
result = {"item_id": item_id, **item.model_dump()}
if q:
result.update({"q": q})
return result
🤓 Other versions and variants
from typing import Union
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Union[str, None] = None
price: float
tax: Union[float, None] = None
app = FastAPI()
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, q: Union[str, None] = None):
result = {"item_id": item_id, **item.model_dump()}
if q:
result.update({"q": q})
return result
関数パラメータは以下のように認識されます:
- パラメータが path でも宣言されている場合、パスパラメータとして使用されます。
- パラメータが 単数型(
int、float、str、boolなど)の場合、query パラメータとして解釈されます。 - パラメータが Pydanticモデル の型として宣言されている場合、リクエスト body として解釈されます。
備考
FastAPIは、デフォルト値 = None があるため、q の値が必須ではないことを認識します。
str | None(Python 3.10+)や Union[str, None](Python 3.9+)の Union は、値が必須ではないことを判断するためにFastAPIでは使用されません。= None というデフォルト値があるため、必須ではないことを認識します。
しかし、型アノテーションを追加すると、エディタがより良いサポートを提供し、エラーを検出できるようになります。
Pydanticを使わない方法¶
Pydanticモデルを使いたくない場合は、Body パラメータも使用できます。Body - Multiple Parameters: Singular values in body のドキュメントを参照してください。