FastAPI教程 直接返回響應(yīng)

2021-11-08 09:46 更新

當(dāng)你創(chuàng)建一個(gè) FastAPI 路徑操作 時(shí),你可以正常返回以下任意一種數(shù)據(jù):dict,list,Pydantic 模型,數(shù)據(jù)庫模型等等。

FastAPI 默認(rèn)會(huì)使用 jsonable_encoder 將這些類型的返回值轉(zhuǎn)換成 JSON 格式,jsonable_encoder 在 JSON 兼容編碼器 中有闡述。

然后,F(xiàn)astAPI 會(huì)在后臺(tái)將這些兼容 JSON 的數(shù)據(jù)(比如字典)放到一個(gè) JSONResponse 中,該 JSONResponse 會(huì)用來發(fā)送響應(yīng)給客戶端。

但是你可以在你的 路徑操作 中直接返回一個(gè) JSONResponse。

直接返回響應(yīng)可能會(huì)有用處,比如返回自定義的響應(yīng)頭和 cookies。

返回 Response

事實(shí)上,你可以返回任意 Response 或者任意 Response 的子類。

小貼士

JSONResponse 本身是一個(gè) Response 的子類。

當(dāng)你返回一個(gè) Response 時(shí),F(xiàn)astAPI 會(huì)直接傳遞它。

FastAPI 不會(huì)用 Pydantic 模型做任何數(shù)據(jù)轉(zhuǎn)換,不會(huì)將響應(yīng)內(nèi)容轉(zhuǎn)換成任何類型,等等。

這種特性給你極大的可擴(kuò)展性。你可以返回任何數(shù)據(jù)類型,重寫任何數(shù)據(jù)聲明或者校驗(yàn),等等。

在 Response 中使用 jsonable_encoder

由于 FastAPI 并未對(duì)你返回的 Response 做任何改變,你必須確保你已經(jīng)準(zhǔn)備好響應(yīng)內(nèi)容。

例如,如果不首先將 Pydantic 模型轉(zhuǎn)換為 dict,并將所有數(shù)據(jù)類型(如 datetime、UUID 等)轉(zhuǎn)換為兼容 JSON 的類型,則不能將其放入JSONResponse中。

對(duì)于這些情況,在將數(shù)據(jù)傳遞給響應(yīng)之前,你可以使用 jsonable_encoder 來轉(zhuǎn)換你的數(shù)據(jù)。

from datetime import datetime
from typing import Optional

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: Optional[str] = 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)

技術(shù)細(xì)節(jié)

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

出于方便,F(xiàn)astAPI 會(huì)提供與 starlette.responses 相同的 fastapi.responses 給開發(fā)者。但是大多數(shù)可用的響應(yīng)都直接來自 Starlette。

返回自定義 Response

上面的例子展示了需要的所有部分,但還不夠?qū)嵱?,因?yàn)槟惚究梢灾皇侵苯臃祷?nbsp;item,而FastAPI 默認(rèn)幫你把這個(gè) item 放到 JSONResponse 中,又默認(rèn)將其轉(zhuǎn)換成了 dict等等。

現(xiàn)在,讓我們看看你如何才能返回一個(gè)自定義的響應(yīng)。

假設(shè)你想要返回一個(gè) XML 響應(yīng)。

你可以把你的 XML 內(nèi)容放到一個(gè)字符串中,放到一個(gè) 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")

說明

當(dāng)你直接返回 Response 時(shí),它的數(shù)據(jù)既沒有校驗(yàn),又不會(huì)進(jìn)行轉(zhuǎn)換(序列化),也不會(huì)自動(dòng)生成文檔。

但是你仍可以參考 OpenApI 中的額外響應(yīng) 給響應(yīng)編寫文檔。

在后續(xù)的章節(jié)中你可以了解到如何使用/聲明這些自定義的 Response 的同時(shí)還保留自動(dòng)化的數(shù)據(jù)轉(zhuǎn)換和文檔等。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)