【FastAPI 學習筆記 EP.4】請求主體 (Request Body)

更新 發佈閱讀 9 分鐘

這篇文章將教你如何在 FastAPI 中定義與接收請求主體 (Request Body),當客戶端需要傳送 JSON 格式的詳細資料給伺服器(例如註冊表單或新增商品)時,就必須使用請求主體 (Request Body)。

什麼是請求主體 (Request Body)?

請求主體 (Request Body) 是客戶端(例如手機 APP、網頁前端)發送給 API 的具體資料內容。它通常以 JSON 格式傳遞,適合包含多個欄位的複雜資料,這與單純透過網址傳遞參數(Query Parameters)不同。

Request Body 基礎概念

Pydantic 模型

FastAPI 使用 Pydantic 來定義資料結構並進行驗證。我們需要創建一個繼承自 BaseModel 的類別,用來告訴 FastAPI 我們期望收到什麼樣的資料。

from pydantic import BaseModel


# 定義訂單模型
class FoodOrder(BaseModel):
    food_name: str
    quantity: int
    is_spicy: bool = False
    note: str | None = None

這段程式碼定義了一個 FoodOrder 模型:

  1. food_name (字串):必填,餐點名稱。
  2. quantity (整數):必填,份數。
  3. is_spicy (布林值):選填,預設為 False (不加辣)。
  4. note (字串或 None):選填,備註欄位,預設為空。

在路徑操作函式中宣告

定義好模型後,將它加入到你的 API 函式參數中,FastAPI 就會自動處理剩下的工作。

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

# 定義訂單模型
class FoodOrder(BaseModel):
    food_name: str
    quantity: int
    is_spicy: bool = False
    note: str | None = None

# 將 order 參數宣告為 FoodOrder 型別
@app.post("/orders/")
def create_order(order: FoodOrder):
    return order

當客戶端發送 POST 請求到 /orders/ 時,FastAPI 會自動讀取 JSON Body,驗證它是否符合 FoodOrder 的結構,並將其轉換為 Python 物件注入到 order 參數中。

自動文件與驗證

FastAPI 不僅會自動攔截錯誤格式的資料,還會根據定義好的模型在 /docs 路徑自動生成互動式 API 文件 (Swagger UI)。

// 前往 http://127.0.0.1:8000/docs 測試 API​
// 如果 quantity 傳了字串 "兩份" (錯誤型別)
// API 會自動回傳 422 Unprocessable Entity

{
  "detail": [
    {
      "type": "int_parsing",
      "loc": [
        "body",
        "quantity"
      ],
      "msg": "Input should be a valid integer, unable to parse string as an integer",
      "input": "兩份"
    }
  ]
}

實作範例

接下來,我們實作一個完整的範例,當收到訂單後,我們根據是否加辣來調整訊息,並計算訂單總結。

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

# 1. 定義資料模型
class FoodOrder(BaseModel):
    food_name: str
    quantity: int
    price_per_unit: int
    is_spicy: bool = False
    note: str | None = None

# 2. 建立 POST 請求處理函式
@app.post("/orders/")
def create_order(order: FoodOrder):
    # 計算總金額
    total_price = order.quantity * order.price_per_unit

    # 建立回覆訊息
    message = f"已收到訂單:{order.quantity}{order.food_name},總金額 ${total_price}"
    if order.is_spicy:
        message += " (備註:要加辣🔥)"

    if order.note:
        message += f" | 客戶備註:{order.note}"

    # 使用 model_dump() 將 Pydantic 物件轉回字典,以便回傳 JSON
    result = order.model_dump()
    result.update({
        "total_price": total_price,
        "message": message,
    })

    return result

在此範例中,如果你傳送 JSON Body:

{"food_name": "牛肉麵", "quantity": 2, "price_per_unit": 150, "is_spicy": true}

API 將會回傳包含總金額 300 以及確認訊息 "已收到訂單:2 份 牛肉麵,總金額 $300 (要加辣🔥)" 的 JSON 資料。

常見錯誤與解決方法

1. 忘記繼承 BaseModel

使用一般的 Python class 來定義結構,這會導致 FastAPI 無法正確將其識別為 JSON Body,而可能將其視為查詢參數,導致驗證失敗。

# ❌ 錯誤寫法:沒有繼承 BaseModel
class User:
    username: str


# ✅ 正確寫法:繼承 BaseModel
from pydantic import BaseModel
class User(BaseModel):
    username: str

2. HTTP 方法使用錯誤

雖然技術上 GET 請求可以攜帶 Body,但在 HTTP 語意規範中,GET 用於「獲取資源」,不應該包含請求主體。若要傳送資料給伺服器處理,請務必使用 POSTPUT

# ❌ 不建議:在 GET 請求中使用 Body
@app.get("/orders/")
def get_order(order: FoodOrder): ...

# ✅ 正確:建立資源使用 POST
@app.post("/orders/")
def create_order(order: FoodOrder): ...

結語

透過 Pydantic 模型,我們可以用非常簡潔的 Python 語法來定義複雜的 API 資料介面。這不僅讓程式碼更易讀,也透過自動驗證減少因為資料格式錯誤導致的 Bug。確保你的模型繼承自 BaseModel,並善用 Python 的型別提示 (Type Hints),就能輕鬆掌握 FastAPI 的請求主體 (Request Body)。

留言
avatar-img
梧笙 WuSheng 的沙龍
65會員
14內容數
⛰️ 梧笙,意即「吾生」,我是一個平凡的理工宅男。 生活離不開 Code 與 Game,這裡主要紀錄與分享: 📖 學習筆記|紀錄我學習過的電腦技能與知識。 💻 科技新知|整理實用工具與科技領域的資訊。 🎮 電玩娛樂|聊聊遊戲動漫與實況直播的話題。 目前更新頻率不固定,有興趣歡迎追蹤。
2025/12/05
這篇文章將教你如何在 FastAPI 中宣告與使用查詢參數 (Query Parameters),讓你能實現資料過濾、搜尋與分頁等功能。
Thumbnail
2025/12/05
這篇文章將教你如何在 FastAPI 中宣告與使用查詢參數 (Query Parameters),讓你能實現資料過濾、搜尋與分頁等功能。
Thumbnail
2025/12/03
這篇文章將教你如何在 FastAPI 中宣告並讀取路徑參數 (Path Parameters),你將學會如何透過 URL 傳遞變數給伺服器,實現取得特定用戶資料或商品資訊等功能。
Thumbnail
2025/12/03
這篇文章將教你如何在 FastAPI 中宣告並讀取路徑參數 (Path Parameters),你將學會如何透過 URL 傳遞變數給伺服器,實現取得特定用戶資料或商品資訊等功能。
Thumbnail
2025/12/01
這篇文章將教你如何在電腦上建置 Python 的 Web 框架:FastAPI,你將學會建立隔離的開發環境、安裝必要套件,並寫出你的第一支 API 程式。
Thumbnail
2025/12/01
這篇文章將教你如何在電腦上建置 Python 的 Web 框架:FastAPI,你將學會建立隔離的開發環境、安裝必要套件,並寫出你的第一支 API 程式。
Thumbnail
看更多
你可能也想看
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」稍微帶大家認識了FastAPI這個框架, 它讓我們快速的架設一個API服務, 並提供了許多標準化功能, 只要照著規範走就能快速的開發出來, 但開發出來之後, 我們會希望開放給一般使用者使用, 而一般使用者較能夠操作的媒介
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」稍微帶大家認識了FastAPI這個框架, 它讓我們快速的架設一個API服務, 並提供了許多標準化功能, 只要照著規範走就能快速的開發出來, 但開發出來之後, 我們會希望開放給一般使用者使用, 而一般使用者較能夠操作的媒介
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」稍微帶大家認識了FastAPI這個框架, 它讓我們快速的架設一個API服務, 並提供了許多標準化功能, 只要照著規範走就能快速的開發出來, 但我們除了能開發出應用之外, 也要設計的更人性化一點, API最重要的就是路由了
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」稍微帶大家認識了FastAPI這個框架, 它讓我們快速的架設一個API服務, 並提供了許多標準化功能, 只要照著規範走就能快速的開發出來, 但我們除了能開發出應用之外, 也要設計的更人性化一點, API最重要的就是路由了
Thumbnail
API是我們與其他系統介接的標準化規格, 那一份好的規格勢必要能夠達到引導與驗證的作用, 避免對方介接錯誤, 引發後續的災難性損失, 因此這一章節就是要教我們如何定義每個API的欄位怎麼填? 資料型態是什麼? 以及如何生成API文件。 我們在「【🔒 Python API框架篇 - Fas
Thumbnail
API是我們與其他系統介接的標準化規格, 那一份好的規格勢必要能夠達到引導與驗證的作用, 避免對方介接錯誤, 引發後續的災難性損失, 因此這一章節就是要教我們如何定義每個API的欄位怎麼填? 資料型態是什麼? 以及如何生成API文件。 我們在「【🔒 Python API框架篇 - Fas
Thumbnail
要如何使用unicorn啟動多個FastAPI服務, 歡迎參考我們的「【💊 Python的解憂錦囊 - FastAPI】如何啟動多個Workers」。 當我們試著設計帶入模組化時… 我們在「【💊 Python的解憂錦囊 - FastAPI】使用 lifespan 來共享資料與管理生命週期
Thumbnail
要如何使用unicorn啟動多個FastAPI服務, 歡迎參考我們的「【💊 Python的解憂錦囊 - FastAPI】如何啟動多個Workers」。 當我們試著設計帶入模組化時… 我們在「【💊 Python的解憂錦囊 - FastAPI】使用 lifespan 來共享資料與管理生命週期
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」有說明如何使用uvicorn來啟動FastAPI服務, 假設今天我們的API是一個CPU密集型的運算服務時, 通常我們會希望開啟多個行程來幫忙處理, 那麼大致上的撰寫方式會像這樣: app = FastAPI( ti
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」有說明如何使用uvicorn來啟動FastAPI服務, 假設今天我們的API是一個CPU密集型的運算服務時, 通常我們會希望開啟多個行程來幫忙處理, 那麼大致上的撰寫方式會像這樣: app = FastAPI( ti
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」有分享 FastAPI 這套API框架, 那麼當我們想要在應用程式剛執行時就註冊一些事件或者共享GPU運算模型、變數…等,當整個應用程式關閉時也進行釋放作業, 這樣的一個週期循環就是所謂的生命週期, 而在FastAPI這
Thumbnail
我們在「【🔒 Python API框架篇 - FastAPI】Ep.1 啟航」有分享 FastAPI 這套API框架, 那麼當我們想要在應用程式剛執行時就註冊一些事件或者共享GPU運算模型、變數…等,當整個應用程式關閉時也進行釋放作業, 這樣的一個週期循環就是所謂的生命週期, 而在FastAPI這
Thumbnail
當我們在開發一個AI應用服務時, 常常會需要載入大模型, But… 我們總不可能每一次的請求就載入一次模型吧! 這樣太沒有效率了, 也非常的浪費資源, 因此我們通常會希望應用程式啟動時就能夠載入模型, 之後每一次的請求只要讓模型進行運算即可, 那麼在FastAPI的框架中究竟要如何使用呢? 首
Thumbnail
當我們在開發一個AI應用服務時, 常常會需要載入大模型, But… 我們總不可能每一次的請求就載入一次模型吧! 這樣太沒有效率了, 也非常的浪費資源, 因此我們通常會希望應用程式啟動時就能夠載入模型, 之後每一次的請求只要讓模型進行運算即可, 那麼在FastAPI的框架中究竟要如何使用呢? 首
Thumbnail
關於FastAPI這個框架為什麼有什麼樣的優勢, 為什麼會這麼熱門? 歡迎參考「【Python 技術選型】如何選出適合的API框架呢?」。 站在巨人的肩膀上 FastAPI主要基於以下兩個重要的元件組成, Starlette與Pydantic, 就讓我們來看看兩者的關係吧! 安裝 pip
Thumbnail
關於FastAPI這個框架為什麼有什麼樣的優勢, 為什麼會這麼熱門? 歡迎參考「【Python 技術選型】如何選出適合的API框架呢?」。 站在巨人的肩膀上 FastAPI主要基於以下兩個重要的元件組成, Starlette與Pydantic, 就讓我們來看看兩者的關係吧! 安裝 pip
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News