资讯动态

FastAPI 直接返回 Response:JSONResponse、jsonable_encoder 与自定义响应实践指南

发布时间:2026/9/8 21:52:37 来源:尧图企业网站定制
FastAPI 直接返回 ResponseJSONResponse、jsonable_encoder 与自定义响应实践指南【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi本文围绕 FastAPI 官方文档《レスポンスを直接返す》docs/ja/docs/advanced/response-directly.md展开讲解如何在 path operation 中直接返回Response对象何时应该直接构造JSONResponse、如何用jsonable_encoder把 Pydantic 模型等数据转换为 JSON 兼容内容、以及如何返回 XML 等完全自定义的响应。读完本文你将理解 FastAPI 对「返回普通数据」与「返回 Response」两条链路的处理差异并能结合 fastapi/routing.py 的源码判断自己项目应该走哪条路径。FastAPI 的默认响应处理方式创建FastAPI的path operation时通常可以返回任意数据dict、list、Pydantic 模型、数据库模型等。默认情况下FastAPI 会按以下规则处理返回值声明了 Response Modelresponse_model参数或返回类型注解时FastAPI 使用 Pydantic 将数据序列化为 JSON未声明 Response Model时FastAPI 使用 JSON 兼容编码器 中介绍的jsonable_encoder把数据转换后放入JSONResponse返回当然你也可以直接构造一个JSONResponse并返回。性能提示通常使用 Response Model 比直接返回JSONResponse性能要好得多因为声明 Response Model 后数据由 Pydantic 在 Rust 层完成序列化。源码视角返回普通数据时的处理路径从源码结构看上述「未声明 Response Model 时走jsonable_encoderJSONResponse」的路径可以在 fastapi/routing.py 中得到印证当 path operation 的返回值不是Response实例时FastAPI 会调用serialize_response内部走jsonable_encoder完成转换再用实际注册的 response class默认为JSONResponse包装内容而当response_field存在即声明了返回类型或 response model且未设置自定义 response class 时源码会启用use_dump_json快速路径——由 Pydantic 的 Rust 核心直接生成 JSON 字节流跳过「中间 Python dict json.dumps()」这一步最终直接构造一个media_typeapplication/json的Response返回见 fastapi/routing.py 处的注释与实现。直接返回Response你可以返回Response或它的任何子类。注意JSONResponse本身就是Response的子类。当返回值是Response实例时FastAPI 会直接把它透传出去不会用 Pydantic 模型做任何数据转换不会把内容转换为任何类型不会执行 Response Model 声明的校验与过滤。这一点在 fastapi/routing.py 中体现得非常直接if isinstance(raw_response, Response): if raw_response.background is None: raw_response.background solved_result.background_tasks response raw_response也就是说返回值是Response时唯一的干预只是在响应没有设置 background 时补上依赖中解析出的后台任务。这种透传带来两方面的影响灵活性可以返回任意数据格式、覆盖任何数据声明或校验责任返回的数据是否正确、格式是否正确、能否被序列化都由你自己保证。在Response中使用jsonable_encoder由于 FastAPI 不会对你返回的Response做任何修改你必须确保其内容已经是可发送的状态。例如不能把一个 Pydantic 模型直接塞进JSONResponse——必须先把它转换成dict且其中所有数据类型如datetime、UUID等都必须是 JSON 兼容类型。此时可以在把数据交给响应之前用jsonable_encoder做转换from datetime import datetime 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: 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(contentjson_compatible_item_data)完整示例见 docs_src/response_directly/tutorial001_py310.py。jsonable_encoder能转换哪些类型jsonable_encoder定义于 fastapi/encoders.py支持include/exclude/by_alias/exclude_unset/exclude_defaults/exclude_none/custom_encoder等参数与 Pydantic 的字段过滤语义一致。从 ENCODERS_BY_TYPE 映射表 可以看到它内置了针对UUID: str、SecretStr: str、SecretBytes: str、Path: str、AnyUrl: str、set: list等类型的转换规则datetime则通过str转换。此外它也能处理 Pydantic 模型实例转为 dict、dataclass、任意对象调用__dict__等。技术细节fastapi.responses与starlette.responses你同样可以from starlette.responses import JSONResponse。FastAPI只是出于开发者便利把starlette.responses中的同名内容以fastapi.responses的形式再提供了一遍。可用的大多数响应类都直接来自 Starlette。从 fastapi/responses.py 可以看到FileResponse、HTMLResponse、JSONResponse、PlainTextResponse、RedirectResponse、Response、StreamingResponse等全部是从starlette.responses直接 re-export 的FastAPI 自身仅额外提供了 SSE 的EventSourceResponse以及已标记弃用的UJSONResponse/ORJSONResponse源码注释说明当设置了返回类型或 response model 时FastAPI 已能通过 Pydantic 直接序列化到 JSON 字节更快且无需自定义响应类。返回自定义Response上面的示例展示了全部所需部件但实用性有限——你完全可以直接返回item让 FastAPI 默认地帮你转成dict并包进JSONResponse。直接返回Response真正的价值在于返回自定义格式的响应。比如你想返回一个 XML 响应。可以把 XML 内容放进字符串塞进Response设置对应的media_type然后返回from fastapi import FastAPI, Response app FastAPI() app.get(/legacy/) def get_legacy_data(): data ?xml version1.0? shampoo Header Apply shampoo here. /Header Body Youll have to use soap here. /Body /shampoo return Response(contentdata, media_typeapplication/xml)完整示例见 docs_src/response_directly/tutorial002_py310.py。由于该返回值是Response实例FastAPI 不会触碰data的内容XML 会按原样发出Content-Type头为application/xml。同样的思路可以扩展到 PDF、CSV、自定义二进制协议等场景。Response Model 的工作机制当你在 path operation 中声明 Response Model返回类型 时FastAPI会用 Pydantic 通过它把数据序列化为 JSONfrom fastapi import FastAPI from pydantic import BaseModel app FastAPI() class Item(BaseModel): name: str description: str | None None price: float tax: float | None None tags: list[str] [] app.post(/items/) async def create_item(item: Item) - Item: return item app.get(/items/) async def read_items() - list[Item]: return [ Item(namePortal Gun, price42.0), Item(namePlumbus, price32.0), ]完整示例见 docs_src/response_model/tutorial001_01_py310.py。因为序列化发生在 Rust 侧性能远好于用常规 Python 加JSONResponse类的做法。使用response_model或返回类型时FastAPI不会使用jsonable_encoder转换数据那会更慢也不会使用JSONResponse类。取而代之的是它直接取 Pydantic 用 response model或返回类型生成的 JSON 字节返回一个携带正确 JSON 媒体类型application/json的Response。这与 fastapi/routing.py 中的use_dump_json快速路径完全对应。备注直接返回Response的边界直接返回Response时数据不会被校验不会被转换序列化不会被自动写入 OpenAPI 文档。不过你仍然可以按照 OpenAPI 中的 Additional Responses 所描述的方式手动为这些响应编写文档。后续章节Custom Response、Response Class 等会介绍如何在继续自动数据转换与文档生成的同时使用/声明这些自定义Response。小结如何选型场景推荐做法原因常规 JSON API声明 Response Model 或返回类型Pydantic Rust 层序列化性能最好且自动校验、过滤、生成文档需要控制 JSON 内容如exclude、自定义头但不想用 response modeljsonable_encoderJSONResponseFastAPI 不干预你自己掌控输出返回 XML / PDF / 其他非 JSON 格式Response(content..., media_type...)或对应子类直接透传任意media_type性能敏感的高频 JSON 端点优先 Response Model避免jsonable_encoder的 Python 侧开销核心原则一句话概括FastAPI 只透传Response其余都帮你做透传的自由度换来了序列化、校验与文档的全部责任。【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价