直接返回响应¶
当你创建一个 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
,同时仍然拥有自动数据转换、文档等功能。