Skip to content

直接返回响应

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

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

然后,在幕后,它会将这些 JSON 兼容的数据(例如 dict)放入 JSONResponse 中,用于发送给客户端。

但你也可以直接从你的 路径操作 中返回一个 JSONResponse

例如,返回自定义的头部或 cookies 时,这可能会很有用。

返回 Response

实际上,你可以返回任何 Response 或其子类。

Tip

JSONResponse 本身就是 Response 的子类。

当你返回一个 Response 时,FastAPI 会直接传递它。

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

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

Response 中使用 jsonable_encoder

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

例如,你不能将 Pydantic 模型直接放入 JSONResponse 中,而必须首先将其转换为包含所有数据类型(如 datetimeUUID 等)的 dict,并转换为 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 的同时,仍然实现自动数据转换、文档化等。