跳转至

直接返回响应

FastAPI 的路径操作支持返回任意数据类型:字典、列表、Pydantic 模型、数据库模型等。

默认情况下,FastAPI 使用 JSON 编码器自动把返回的值转换为 JSON。

然后,FastAPI 在后台把兼容 JSON 的数据(比如字典)放到向客户端发送响应的 JSONResponse 里。

但其实路径操作可以直接返回 JSONResponse。

返回自定义请求头或 Cookie 时经常使用这种方式。

返回 Response

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

提示

JSONResponse 就是 Response 的子类。

FastAPI 直接传递返回的 Response。

此时不使用 Pydantic 模型转换任何数据,也不转换数据类型。

这种方式很灵活,能返回任何数据类型,或覆盖数据声明、验证等操作。

在 Response 中使用 jsonable_encoder

FastAPI 不修改返回的 Response,因此必须要事先确认它的内容没有任何问题。

例如,把 Pydantic 模型放入 JSONResponse 前,要先把它转换为所有数据类型(如 datetime、UUID 等)都兼容 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

上例介绍了所有要了解的知识点,但并不是很实用,因为 FastAPI 本来就会直接返回 item,把它放入 JSONResponse,然后转换成字典,这些操作都是默认的。

接下来,我们学习如何返回自定义响应。

比如说,返回 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 时,FastAPI 不会验证、转换(序列化)和自动存档 Response 中的数据。

但仍可以使用 OpenAPI 中的附加响应 一章里的方式进行存档。

下一章介绍如何声明并使用自定义 Response,同时实现自动数据转换、存档等功能。