跳到内容

直接返回响应

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

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

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

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

例如,这可能对于返回自定义头部或 Cookie 很有用。

返回一个 Response

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

提示

JSONResponse 本身就是 Response 的一个子类。

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

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

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

Response 中使用 jsonable_encoder

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

例如,你不能在没有首先将其转换为 `dict`(其中所有数据类型,如 `datetime`、`UUID` 等,都已转换为 JSON 兼容类型)的情况下,将 Pydantic 模型直接放入 `JSONResponse` 中。

对于这些情况,你可以在将数据传递给响应之前,使用 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 提供与 starlette.responses 相同的 fastapi.responses,只是为了方便开发者。但大多数可用的响应都直接来自 Starlette。

返回一个自定义的 Response

上面的示例展示了你所需的所有部分,但它目前并不是很有用,因为你可以直接返回 item,而 FastAPI 会为你将其放入 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,同时仍然拥有自动数据转换、文档等功能。