直接返回响应¶
创建 FastAPI 路径操作 时,通常可以返回任何数据:dict
、list
、Pydantic 模型、数据库模型等。
默认情况下,FastAPI 会使用 JSON 兼容编码器 中解释的 jsonable_encoder
自动将该返回值转换为 JSON。
然后,在后台,它会将该 JSON 兼容数据(例如,dict
)放在 JSONResponse
中,该 JSONResponse
将用于将响应发送到客户端。
但是,您也可以直接从您的 路径操作 返回 JSONResponse
。
例如,它可能很有用,用于返回自定义标头或 Cookie。
返回 Response
¶
实际上,您可以返回任何 Response
或它的任何子类。
提示
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 提供与 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
。