Skip to content

直接回傳 Response

🌐 AI 與人類共同完成的翻譯

此翻譯由人類指導的 AI 完成。🤝

可能會有對原意的誤解,或讀起來不自然等問題。🤖

你可以透過協助我們更好地引導 AI LLM來改進此翻譯。

英文版

當你建立一個 FastAPI 的路徑操作 (path operation) 時,通常可以從中回傳任何資料:dictlist、Pydantic 模型、資料庫模型等。

預設情況下,FastAPI 會使用在JSON 相容編碼器中說明的 jsonable_encoder,自動將回傳值轉為 JSON。

然後在幕後,它會把這些與 JSON 相容的資料(例如 dict)放進 JSONResponse,用來把回應傳回給用戶端。

但你也可以直接從路徑操作回傳 JSONResponse

例如,當你需要回傳自訂的 headers 或 cookies 時就很有用。

回傳 Response

其實,你可以回傳任何 Response,或其任何子類別。

Tip

JSONResponse 本身就是 Response 的子類別。

當你回傳一個 Response 時,FastAPI 會直接傳遞它。

它不會對 Pydantic 模型做任何資料轉換,也不會把內容轉成其他型別等。

這給了你很大的彈性。你可以回傳任何資料型別、覆寫任何資料宣告或驗證等。

Response 中使用 jsonable_encoder

因為 FastAPI 不會對你回傳的 Response 做任何更動,你需要自行確保它的內容已經準備好。

例如,你不能直接把一個 Pydantic 模型放進 JSONResponse,需要先把它轉成 dict,並將所有資料型別(像是 datetimeUUID 等)轉成與 JSON 相容的型別。

在這些情況下,你可以先用 jsonable_encoder 把資料轉好,再傳給回應物件:

from datetime import datetime

from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
from pydantic import BaseModel


class Item(BaseModel):
    title: str
    timestamp: datetime
    description: str | None = None


app = FastAPI()


@app.put("/items/{id}")
def update_item(id: str, item: Item):
    json_compatible_item_data = jsonable_encoder(item)
    return JSONResponse(content=json_compatible_item_data)

技術細節

你也可以使用 from starlette.responses import JSONResponse

FastAPI 為了方便開發者,將 starlette.responses 也提供為 fastapi.responses。但大多數可用的回應類型其實直接來自 Starlette。

回傳自訂 Response

上面的範例展示了所需的各個部分,但目前還不太實用,因為你其實可以直接回傳 itemFastAPI 就會幫你把它放進 JSONResponse,轉成 dict 等,這些都是預設行為。

現在來看看如何用它來回傳自訂回應。

假設你想要回傳一個 XML 回應。

你可以把 XML 內容放進一個字串,把它放進 Response,然後回傳它:

from fastapi import FastAPI, Response

app = FastAPI()


@app.get("/legacy/")
def get_legacy_data():
    data = """<?xml version="1.0"?>
    <shampoo>
    <Header>
        Apply shampoo here.
    </Header>
    <Body>
        You'll have to use soap here.
    </Body>
    </shampoo>
    """
    return Response(content=data, media_type="application/xml")

注意事項

當你直接回傳 Response 時,其資料不會自動被驗證、轉換(序列化)或文件化。

但你仍然可以依照在 OpenAPI 中的額外回應中的說明進行文件化。

在後續章節中,你會看到如何在仍保有自動資料轉換、文件化等的同時,使用/宣告這些自訂的 Response