直接返回响应¶
当你创建 FastAPI 路径操作时,通常可以从中返回任何数据:dict、list、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 中,而不先将其转换为 dict,并将所有数据类型(如 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 提供与 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 的同时,仍具有自动数据转换、文档记录等功能。