直接返回响应¶
当你创建一个 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
中,而必须首先将其转换为包含所有数据类型(如 datetime
、UUID
等)的 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
¶
上面的例子展示了你需要的所有部分,但它还不是很有用,因为你本可以直接返回 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
的同时,仍然实现自动数据转换、文档化等。