直接返回响应¶
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,同时实现自动数据转换、存档等功能。