前言
- 上一篇有講到將參數類型指定為 Pydantic Model,這樣 FastAPI 會解析它為一個 Request Body
- 那單類型(int、float、str、bool...)參數可以成為 Request Body 的一部分嗎?答案是可以的
- 通過 Body 函數即可完成,和 Path、Query 有異曲同工之妙
文章跳轉
Body
- 主要作用:可以將單類型的參數成為 Request Body 的一部分,即從查詢參數變成請求體參數
- 和 Query、Path 提供的額外校驗、元數據是基本一致的(多了個 embed 參數,最后講解)

Body 的簡單栗子
from typing import Optional import uvicorn from fastapi import Body, FastAPI from pydantic import BaseModel app = FastAPI() class Item(BaseModel): name: str description: Optional[str] = None price: float tax: Optional[float] = None class User(BaseModel): username: str full_name: Optional[str] = None @app.put("/items/{item_id}") async def update_item( item_id: int, item: Item, user: User, importance: int = Body(...) ): results = {"item_id": item_id, "item": item, "user": user, "importance": importance} return results if __name__ == "__main__": uvicorn.run(app="8_Body:app", host="127.0.0.1", port=8080, reload=True, debug=True)
期望得到的 Request Body
{ "item": { "name": "Foo", "description": "The pretender", "price": 42.0, "tax": 3.2 }, "user": { "username": "dave", "full_name": "Dave Grohl" }, "importance": 5 }
Request Body 中多了個 importance
正確傳參的請求結果

查看 Swagger API 文檔

Query、Path、Body 終極混用
from typing import Optional import uvicorn from fastapi import Body, FastAPI, Path, Query from pydantic import BaseModel app = FastAPI() class Item(BaseModel): name: str description: Optional[str] = None price: float tax: Optional[float] = None class User(BaseModel): username: str full_name: Optional[str] = None @app.put("/item_all/{item_id}") async def update_item( *, item_id: int = Path(default=..., description="路徑參數", gt=0, lt=10), address: str = Query(default=None, description="查詢參數", max_length=10), item: Item, user: User, importance: int = Body(default=..., description="請求體", ge=1, le=5) ): results = { "item_id": item_id, "address": address, "item": item, "user": user, "importance": importance } return results
正確傳參的請求結果

查看 Swagger API 文檔

Body() 中的 embed 參數
為什么要講這個 embed 參數
當函數只有一個參數指定了 Pydantic Model 且沒有其他 Body 參數時,傳參的時候請求體可以不指定參數名
class Item(BaseModel): name: str description: Optional[str] = None price: float tax: Optional[float] = None @app.put("/items/{item_id}") async def update_item(item_id: int, item: Item): ...
期望得到的請求體
{ "name": "Foo", "description": "The pretender", "price": 42.0, "tax": 3.2 }
默認並不需要指定 item 為字段名
那假設想指定 item 為請求體的字段名呢?就是通過 embed 參數達到目的了
實際代碼
from typing import Optional from fastapi import Body, FastAPI from pydantic import BaseModel app = FastAPI() class Item(BaseModel): name: str description: Optional[str] = None price: float tax: Optional[float] = None @app.put("/items/{item_id}") async def update_item( *, item_id: int, # 將 embed 設置為 True item: Item = Body(..., embed=True)): results = {"item_id": item_id, "item": item} return results
期望得到的請求體
{ "item": { "name": "Foo", "description": "The pretender", "price": 42.0, "tax": 3.2 } }
正確傳參的請求結果

還是不傳 item 字段的請求結果

查看 Swagger API 文檔

