FastAPI 請求主體 (Request Body)
當你需要從客戶端(例如瀏覽器或前端 App)接收資料時,通常會透過 Request Body (請求主體) 來傳送。在 FastAPI 中,我們使用 Pydantic 模型來定義 Body 的結構和驗證規則。
Request Body 通常用於
POST, PUT, DELETE, PATCH 等方法。GET 請求雖然技術上可以帶 Body,但通常不建議這麼做。定義資料模型 (Pydantic Model)
首先,你需要從 pydantic 模組導入 BaseModel,並建立一個繼承自它的類別。
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
app = FastAPI()
@app.post("/items/")
async def create_item(item: Item):
return item
當你將 Pydantic 模型宣告為參數時,FastAPI 會幫你做以下事情:
- 讀取 Body:將 HTTP 請求的 Body 讀取出來 (假設是 JSON)。
- 轉換型別:如果需要,會自動轉換型別 (例如 JSON 的
12.5轉成 Python 的float)。 - 資料驗證:
- 如果資料缺少必填欄位 (如
name,price),會報錯。 - 如果資料型別錯誤 (如
price傳了字串 "abc"),會報錯。
- 如果資料缺少必填欄位 (如
- 賦值:將驗證後的資料放入
item參數中。此時item是一個Item物件,你可以像存取屬性一樣使用它 (如item.name)。 - 產生 Schema:自動產生 JSON Schema 定義,供 Swagger UI 使用。
使用模型資料
在函數內部,你可以直接操作這個 Pydantic 物件:
@app.post("/items/")
async def create_item(item: Item):
# Pydantic v2 使用 model_dump() 取代舊版的 dict()
item_dict = item.model_dump()
if item.tax:
price_with_tax = item.price + item.tax
item_dict.update({"price_with_tax": price_with_tax})
return item_dict
如果你使用的是 Pydantic v1 (FastAPI 較舊版本),請使用
item.dict()。但在 FastAPI 最新版本中 (搭配 Pydantic v2),建議使用 model_dump()。路徑參數 + 查詢參數 + 請求主體
FastAPI 能夠同時處理三種參數來源,它會自動識別:
- 如果在路徑
{}中有宣告 -> 路徑參數。 - 如果是
Pydantic模型型別 -> 請求主體 (Request Body)。 - 如果是一般型別 (int, str, float...) 且不在路徑中 -> 查詢參數。
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, q: Optional[str] = None):
result = {"item_id": item_id, **item.dict()}
if q:
result.update({"q": q})
return result
在這個例子中,FastAPI 知道:
item_id來自 URL 路徑。item來自 Request Body。q來自 Query String。
請求主體與驗證錯誤
如果你傳送無效的資料,例如缺少 price 欄位:
Request:
{
"name": "Foo",
"description": "An optional description"
}
Response (422 Unprocessable Entity):
{
"detail": [
{
"loc": ["body", "price"],
"msg": "field required",
"type": "value_error.missing"
}
]
}
這大大簡化了後端開發驗證資料的繁瑣工作。
總結
- 使用
Pydantic的BaseModel來定義資料結構。 - 將定義好的 Model 宣告為函數參數,即可接收並驗證 JSON Body。
- Pydantic v2 推薦使用
model_dump()來將模型轉換為字典。 - 可以自訂必填欄位 (無預設值) 與選填欄位 (有預設值)。
- FastAPI 能夠完美混合使用 Body、Path 和 Query 參數。