
FastAPI 高频实用技巧指南响应数据安全过滤、JSON 编码与 OpenAPI 文档定制【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapiGeneral - How To - Recipes西班牙语版 与 英语原文 是 FastAPI 文档「How-To」部分的入口页之一它不像逐章教程那样系统推进而是把开发中最常遇到的十类问题如何过滤返回数据、如何优化响应性能、如何为接口打标签、如何定制自动文档等整理成一条条独立可用的「菜谱」并精确指向文档中对应的深入章节。本指南将以这份菜谱清单为骨架结合仓库内的可运行示例docs_src/与核心源码fastapi/逐一展开每个技巧的原理、完整代码与底层依据让你拿到一份可直接照着做的实战手册。阅读完整篇文章后你将能够用response_model/返回类型声明保证“只返回该返回的字段”在 PydanticRust 内核序列化层面优化 JSON 响应性能用装饰器参数为路径操作添加标签、摘要、响应说明与弃用标记把任意数据一键转成 JSON 兼容结构并自由定制 OpenAPI 的元数据、Schema URL 与两套文档界面Swagger UI / ReDoc的地址。菜谱地图这篇文章对应仓库中的哪些内容菜谱原文标题文章小节深入文档可运行源码Filtrar Datos - Seguridad数据安全过滤response-model.mddocs_src/response_model/Optimizar el Rendimiento del Response性能优化与 Rust 侧序列化response-model.mddocs_src/response_model/Etiquetas de DocumentaciónOpenAPI 标签tagspath-operation-configuration.md#tagsdocs_src/path_operation_configuration/tutorial002_py310.pyResumen y Descripción摘要与描述summary/descriptionpath-operation-configuration.mddocs_src/path_operation_configuration/tutorial003_py310.pyDescripción del Response响应描述response_descriptionpath-operation-configuration.mddocs_src/path_operation_configuration/tutorial005_py310.pyDeprecación弃用标记deprecatedpath-operation-configuration.mddocs_src/path_operation_configuration/tutorial006_py310.pyConvertir Datos a JSON-compatibleJSON 兼容编码器encoder.mddocs_src/encoder/tutorial001_py310.pyMetadatos OpenAPIOpenAPI 元数据定制metadata.mddocs_src/metadata/URL Personalizada de OpenAPIOpenAPI URL 定制与禁用metadata.md#openapi-urldocs_src/metadata/tutorial002_py310.pyURLs de Documentación文档界面 URL 定制metadata.md#docs-urlsdocs_src/metadata/tutorial003_py310.py这些菜谱彼此相对独立按需取用即可不必一次全部读完。需要系统学习时可以按章节阅读 Tutorial - User Guide或查看整个 How-To 目录的说明入口 index.md。数据安全过滤用好 response_model 防止返回多余数据菜谱原文的第一条提醒是确保你不会返回超出预期的数据。这是 Web API 最常踩的坑之一——比如返回体里夹带了用户密码、内部 ID 或数据库中多余的列。声明返回类型的基础收益给路径操作函数标注返回类型注解与请求参数使用同一种方式可以声明 Pydantic 模型、list、dict、int、bool等任意类型。见示例 tutorial001_01_py310.py。FastAPI 会据此校验返回数据若字段缺失或形状不符说明是应用自身代码的 bug会返回服务器错误而不是“错误形状的正确数据”客户端可以确信收到符合预期的数据在 OpenAPI 中为响应生成JSON Schema供自动文档与客户端代码生成工具使用序列化返回数据为 JSON见下节“性能优化”最关键的是限制并过滤输出数据到返回类型声明的范围——这正是安全性的来源。什么时候用response_model而不是返回类型如果你希望“函数内返回一个字典或数据库对象但对外声明成一个 Pydantic 模型”直接用返回类型注解会让编辑器和 mypy 报错函数确实返回了与声明不一致的类型。此时应改用路径操作装饰器参数response_model它可用于app.get()、app.post()、app.put()、app.delete()等任意操作。注意response_model是装饰器方法get/post的参数不是你的路径操作函数的参数。若同时声明返回类型与response_modelresponse_model优先。因此你可以既保留正确的类型注解以取悦编辑器/mypy又让 FastAPI 按response_model完成数据文档、校验与过滤。如果某些注解不是合法的 Pydantic 字段例如返回Response与dict的联合类型会直接报错可以用response_modelNone为这条路径操作关闭响应模型生成。经典防泄露示例输入模型与输出模型分离用同一个模型做输入输出是危险的。参考 tutorial002_py310.pyUserIn含password字段创建用户接口把它原样返回等于把明文密码送回给每个客户端。正确做法是拆成两个模型tutorial003_py310.pyfrom typing import Any from fastapi import FastAPI from pydantic import BaseModel, EmailStr app FastAPI() class UserIn(BaseModel): username: str password: str email: EmailStr full_name: str | None None class UserOut(BaseModel): username: str email: EmailStr full_name: str | None None app.post(/user/, response_modelUserOut) async def create_user(user: UserIn) - Any: return user # 内部返回的是含 password 的 UserIn这里即使函数实际返回的是包含密码的UserIn因为声明了response_modelUserOutFastAPI 会用 Pydantic 过滤掉所有未在输出模型中声明的字段密码永远不会进入响应。EmailStr需要先安装email-validatoruv add email-validator或uv add pydantic[email]。用继承兼得类型检查与数据过滤上面的写法让函数丢掉了“返回类型正确”的编辑器支持。大多数“只需过滤掉部分字段”的场景可以用类继承解决tutorial003_01_py310.py定义BaseUser承载基础字段UserIn(BaseUser)追加password并把函数返回类型注解为BaseUser。类型系统认为UserIn是BaseUser的子类、注解合法编辑器/mypy 不会抱怨而 FastAPI 过滤返回数据时不会套用继承规则仍然只保留返回类型声明的字段。这样“类型注解的工具链支持”与“数据过滤”两者兼得。编码参数控制默认值是否进入响应当模型字段带默认值如tax: float 10.5、tags: List[str] []而数据并未真正存储这些值时可能不希望响应被长长的默认值撑满。可在装饰器上设置response_model_exclude_unsetTrue只包含真正被显式赋值的字段默认值不算response_model_exclude_defaultsTrue排除取值等于默认值的字段response_model_exclude_noneTrue排除值为None的字段。这里有个值得注意的细节对应仓库测试与文档说明如果数据显式设置了与默认值相同的值比如显式传了tax10.5Pydantic 仍会保留它因为“显式赋值”与“取默认值”是两种状态。另外response_model_include与response_model_exclude可接收一个set/listlist会被自动转成set来快速裁切字段。但官方更推荐用“多类 返回类型”方案因为include/exclude并不会改变 OpenAPI 中生成的完整模型 Schema同理response_model_by_alias也适用这一提醒。响应性能优化Pydantic Rust 内核完成 JSON 序列化菜谱的第二条提示面向性能返回 JSON 时使用返回类型或response_model。原因是 Pydantic v2 的序列化核心用 Rust 实现pydantic-coreFastAPI 会借助 Pydantic 在 Rust 侧完成向 JSON 数据的序列化转换而不必在 Python 侧逐字段手工拼接。声明响应模型的同时校验、文档与过滤也随之免费获得。这也解释了为什么要尽量“用类型声明响应”而不是裸返回dict显式类型让 FastAPI 能跳过不确定的运行时猜测路径把序列化交给经过充分优化的 Pydantic 管线处理。仓库中大量相关测试如 tests/test_serialize_response.py、tests/test_serialize_response_model.py都在回归验证“模型声明下响应被正确序列化与裁剪”的行为。为路径操作添加 OpenAPI 标签tags为了让自动文档按业务域分组可以在路径操作装饰器上传入tags参数一个str列表通常只有一个字符串。完整的对照示例见 tutorial002_py310.pyapp.post(/items/, tags[items]) async def create_item(item: Item) - Item: return item app.get(/items/, tags[items]) async def read_items(): return [{name: Foo, price: 42}] app.get(/users/, tags[users]) async def read_users(): return [{username: johndoe}]这些标签会进入 OpenAPI Schema并在 Swagger UI / ReDoc 界面中把属于同一标签的接口聚合到一组。需要保证标签拼写一致时可以把标签放进Enum见 tutorial002b_py310.py与普通字符串用法完全相同。为路径操作添加摘要与描述通过装饰器参数summary与description可以为路径操作添加说明文字示例 tutorial003_py310.pyapp.post( /items/, summaryCreate an item, descriptionCreate an item with all the information, ) async def create_item(item: Item) - Item: return item描述通常较长、跨多行官方更推荐直接写在路径操作函数的docstring里见 tutorial004_py310.pydocstring 支持 Markdown 语法FastAPI 会自动读取并正确渲染会考虑缩进。示例中使用- **name**: ...这样的列表/加粗写法最终会在交互文档中显示成带格式的富文本。为响应单独编写描述response_descriptionresponse_description描述的是响应本身而description描述的是整个路径操作——两者语义不同不要把两者混用。OpenAPI 规范要求每条路径操作都必须有响应描述若你未提供FastAPI 会自动补一条 “Successful response”。用法示例tutorial005_py310.pyapp.post( /items/, summaryCreate an item, response_descriptionThe created item, ) async def create_item(item: Item) - Item: return item标记路径操作已弃用deprecated在接口需要“标记废弃但不删除”时传入布尔参数deprecatedTrue示例 tutorial006_py310.pyapp.get(/elements/, tags[items], deprecatedTrue) async def read_elements(): return [{item_id: Foo}]文档界面会以明显的视觉样式区分 deprecated 与非 deprecated 的接口同时该标记也会写入 OpenAPI Schema提醒下游调用方及时迁移。以上路径操作配置的装饰器参数状态码、标签、摘要、描述、响应描述、弃用等都直接传给装饰器而不是传给路径操作函数这是阅读源码时最容易误解的一点仓库测试 tests/test_operations_signatures.py 等对这类参数签名做了约束验证。把任意数据转换为 JSON 兼容结构jsonable_encoderdatetime对象、Pydantic 模型这类数据无法直接被 Python 标准json编码也不适合直接存入只接受 JSON 兼容数据的存储层。FastAPI 提供的jsonable_encoder()专门解决这个问题它接收任意对象返回一个值及子值全部 JSON 兼容的标准 Python 结构如dict/list可直接交给json.dumps()或塞进数据库。注意它的返回并不是一个大的 JSON 字符串而是结构化的 Python 容器。官方用例tutorial001_py310.pyfrom datetime import datetime from fastapi import FastAPI from fastapi.encoders import jsonable_encoder from pydantic import BaseModel fake_db {} 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) fake_db[id] json_compatible_item_data本例中Item被转成dict其中的datetime被转成 ISO 8601 格式字符串之后就能安全存入fake_db。函数实现在 fastapi/encoders.pyFastAPI 内部也正是用它对数据进行编码所以这条菜谱不仅适用于存储也解释了 FastAPI 响应处理管线中的一环。定制 OpenAPI 顶层元数据title/version/contact/license 等在创建FastAPI()实例时可以设置以下会进入 OpenAPI 规范并呈现在文档界面中的字段完整示例 tutorial001_py310.py参数类型说明titlestrAPI 的标题summarystrAPI 的简短概述OpenAPI 3.1.0 / FastAPI 0.99.0 起支持descriptionstrAPI 的描述支持 Markdownversionstr你自己应用的版本号例如2.5.0不是 OpenAPI 的版本terms_of_servicestr服务条款 URL必须是合法 URLcontactdict联系信息可含name联系人/组织名、url联系信息 URL、email合法邮箱license_infodict许可证信息name必填一旦设置license_info则必须提供、url或 OpenAPI 3.1.0 起新增的identifierSPDX 许可证表达式与url互斥典型写法app FastAPI( titleChimichangApp, descriptionChimichangApp API helps you do awesome stuff. \n\n## Items\n\nYou can **read items**., summaryDeadpools favorite app. Nuff said., version0.0.1, terms_of_servicehttp://example.com/terms/, contact{ name: Deadpoolio the Amazing, url: http://x-force.example.com/contact/, email: dpx-force.example.com, }, license_info{ name: Apache 2.0, url: https://www.apache.org/licenses/LICENSE-2.0.html, }, )使用 SPDXidentifier的写法可参考 tutorial001_1_py310.py。若想让description中的 Markdown 正常渲染直接写即可文档界面会按 Markdown 处理。标签级元数据openapi_tags除了顶层元数据还能用openapi_tags为文档分组补充说明示例 tutorial004_py310.py。它接收一个列表每个元素是对应一个标签的字典name必填与你路径操作/APIRouter中tags使用的标签名一致description标签说明支持 MarkdownexternalDocs外部文档字典含description与必填的url。列表里字典的顺序决定标签在文档界面的展示顺序可以覆盖字母序。你不必为所有用到的标签都补充元数据。定制或禁用OpenAPI URL默认 OpenAPI Schema 服务在/openapi.json。通过openapi_url参数可以改地址例如放到/api/v1/openapi.json示例 tutorial002_py310.pyapp FastAPI(openapi_url/api/v1/openapi.json)若想彻底关闭 OpenAPI将其设为openapi_urlNone依赖它的文档界面也会一并停用。从 fastapi/applications.py 的参数文档可以看到该参数的默认值即/openapi.json且仅当openapi_url非空时应用才会注册对应路由与docs/redoc界面相关逻辑位于 fastapi/applications.py。如果场景更复杂例如希望依据环境变量条件性地开/关文档可参考 conditional-openapi.md 中“用 Pydantic Settings 配置 OpenAPI”的做法并结合 conditional_openapi/tutorial001_py310.py。需要提醒的是隐藏生产环境的文档界面不应成为保护 API 的手段——接口本身仍然可达安全缺陷依然存在这更接近“通过隐匿实现安全”。正确的加固方向是明确定义 Pydantic 模型、用依赖实现权限与角色控制、绝不存储明文密码、采用成熟的密码哈希与 JWT 等方案、必要时用 OAuth2 scopes 细化权限。定制文档界面的 URLdocs_url 与 redoc_urlFastAPI 内置两套自动文档界面均可独立定制或禁用Swagger UI默认在/docs用docs_url改地址设docs_urlNone禁用ReDoc默认在/redoc用redoc_url改地址设redoc_urlNone禁用。例如把 Swagger UI 放到/documentation并停用 ReDoc示例 tutorial003_py310.pyapp FastAPI(docs_url/documentation, redoc_urlNone)这两个参数在 fastapi/applications.py 中均有详细注解若openapi_url设为None两者会自动随之禁用。测试层面仓库在 tests/test_application.py、tests/test_custom_swagger_ui_redirect.py 等文件中对这些 URL 的注册与重定向行为做了完整验证。小结与建议对照这份 FastAPI 官方 “General How-To Recipes” 清单可以沉淀出几条立即可用的开发习惯永远声明响应形状返回类型或response_model让 FastAPI/Pydantic 过滤数据、生成 Schema 并加速序列化输出模型与输入模型分离是防止密码等敏感字段外泄的第一道闸门装饰器参数是文档化的主入口tags、summary、description、response_description、deprecated全部作用于“整条路径操作”应在装饰器上传参而非函数体内面向存储的 JSON 转换统一走jsonable_encoder不要手工处理datetime等类型应用元数据与文档地址在FastAPI()实例化时一次性声明可用环境变量与 Settings 驱动条件开关但不要指望“关掉文档”来保障 API 安全。文中每个示例的完整可运行源码都在仓库docs_src/相应目录下对应主题的逐章讲解见 Tutorial 目录需要进一步了解其他“如何做”型话题认证错误码、条件化 OpenAPI、自定义文档资源、Pydantic v1 迁移等时可以直接浏览整个 How-To 目录。【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考