跳至内容

直接返回响应

创建 FastAPI 路径操作 时,通常可以返回任何数据:dictlist、Pydantic 模型、数据库模型等。

默认情况下,FastAPI 会使用 JSON 兼容编码器 中解释的 jsonable_encoder 自动将该返回值转换为 JSON。

然后,在后台,它会将该 JSON 兼容数据(例如,dict)放在 JSONResponse 中,该 JSONResponse 将用于将响应发送到客户端。

但是,您也可以直接从您的 路径操作 返回 JSONResponse

例如,它可能很有用,用于返回自定义标头或 Cookie。

返回 Response

实际上,您可以返回任何 Response 或它的任何子类。

提示

JSONResponse 本身就是 Response 的子类。

当您返回 Response 时,FastAPI 会直接传递它。

它不会对您返回的 Pydantic 模型进行任何数据转换,也不会将内容转换为任何类型等。

这为您提供了很大的灵活性。您可以返回任何数据类型,覆盖任何数据声明或验证等。

Response 中使用 jsonable_encoder

因为 FastAPI 不会对您返回的 Response 进行任何更改,所以您必须确保其内容已准备好。

例如,您不能将 Pydantic 模型放入 JSONResponse 中,而没有先将其转换为 dict,并将所有数据类型(如 datetimeUUID 等)转换为 JSON 兼容类型。

对于这些情况,您可以使用 jsonable_encoder 将您的数据转换为可以放入响应中的类型

from datetime import datetime
from typing import Union

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: Union[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 提供与 fastapi.responses 相同的 starlette.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