FastAPI 附加状态码(Additional Status Codes):在同一路径操作中返回 200 与 201
FastAPI 附加状态码Additional Status Codes在同一路径操作中返回 200 与 201【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi在 FastAPI 中路径操作path operation默认统一返回JSONResponse并使用默认状态码或你在装饰器中显式设置的status_code。但在真实业务中更新或创建upsert这类接口往往需要在一个端点里同时返回 200 OK更新已有资源与 201 Created新建资源。本指南以 FastAPI 官方进阶文档Additional Status Codes为核心讲解如何通过直接返回Response如JSONResponse来附加状态码并深入仓库源码与测试用例说明其底层行为、注意事项以及如何与 OpenAPI 文档配合。默认行为一个路径操作只能有一个主状态码默认情况下FastAPI会使用JSONResponse返回响应并将你在路径操作中返回的内容放入该JSONResponse中。状态码取自以下二者之一默认状态码未指定时为 200 OK你在路径操作装饰器中通过status_code参数显式设置的状态码。从源码看路由层会在响应序列化阶段统一处理状态码routing.py 中根据显式传入的status_code或依赖解析结果来决定最终的响应状态码若未设置则使用默认值 200。这也意味着单个路径操作在主状态码层面只能有一个值。附加状态码直接返回 Response如果你想在返回主状态码之外还返回其他状态码可以通过直接返回一个Response对象例如JSONResponse来实现并在构造时直接指定status_code。典型场景假设你有一个允许更新条目的路径操作成功时返回 200 OK同时你还希望它接受新条目——当条目之前不存在时创建它并返回 201 Created。完整示例官方教程代码以下代码来自仓库中的 docs_src/additional_status_codes/tutorial001_an_py310.py演示了 upsert 语义from typing import Annotated from fastapi import Body, FastAPI, status from fastapi.responses import JSONResponse app FastAPI() items {foo: {name: Fighters, size: 6}, bar: {name: Tenders, size: 3}} app.put(/items/{item_id}) async def upsert_item( item_id: str, name: Annotated[str | None, Body()] None, size: Annotated[int | None, Body()] None, ): if item_id in items: item items[item_id] item[name] name item[size] size return item else: item {name: name, size: size} items[item_id] item return JSONResponse(status_codestatus.HTTP_201_CREATED, contentitem)仓库同时提供了不使用Annotated的等价版本tutorial001_py310.py其请求体参数写作name: str | None Body(defaultNone)业务逻辑完全一致。代码要点解析当item_id已存在于items中如foo、bar走更新分支直接返回字典item由 FastAPI 默认的JSONResponse序列化状态码为 200当item_id不存在如red走创建分支手动构造JSONResponse设置status_codestatus.HTTP_201_CREATED即 201并指定contentitem作为响应体status.HTTP_201_CREATED来自fastapi.status比硬编码数字 201 更可读、更不易出错。测试用例验证仓库在 tests/test_tutorial/test_additional_status_codes/test_tutorial001.py 中为上述两个教程版本提供了完整的测试用TestClient直接验证两种状态码路径def test_update(client: TestClient): response client.put(/items/foo, json{name: Wrestlers}) assert response.status_code 200, response.text assert response.json() {name: Wrestlers, size: None} def test_create(client: TestClient): response client.put(/items/red, json{name: Chillies}) assert response.status_code 201, response.text assert response.json() {name: Chillies, size: None}其中test_update验证更新已有条目返回 200test_create验证新建条目返回 201且两者响应体内容都符合预期。该测试以参数化方式同时覆盖tutorial001_py310与tutorial001_an_py310两个版本needs_py310标记要求 Python 3.10。关键警告直接返回 Response 不会被序列化当你像上面的例子一样直接返回一个Response时它会原样返回它不会经过响应模型response model等机制的序列化处理使用JSONResponse时请确保content中的数据正是你想要返回的内容并且值都是合法的 JSON。这与返回普通 Python 对象字典、Pydantic 模型等的路径不同——后者会由 FastAPI 在内部序列化并应用过滤/校验逻辑。直接返回Response相当于把响应构造的控制权完全交给了你。技术细节fastapi.responses 与 starlette.responses你也可以使用from starlette.responses import JSONResponse。FastAPI提供与starlette.responses相同的fastapi.responses命名空间仅仅是出于方便开发者的考虑——大多数可用的响应类JSONResponse、HTMLResponse、PlainTextResponse、RedirectResponse、StreamingResponse、FileResponse等都直接来自 Starlettestatus模块也是如此。从源码看fastapi/responses.py 中的核心响应类都是对 Starlette 同名类的直接再导出re-export例如from starlette.responses import JSONResponse as JSONResponse # noqa from starlette.responses import Response as Response # noqa from starlette.responses import HTMLResponse as HTMLResponse # noqa另外注意该文件中的UJSONResponse与ORJSONResponse已被标记为deprecated弃用注释明确说明FastAPI now serializes data directly to JSON——即 FastAPI 现在直接序列化数据为 JSON不再需要这两个高性能响应类。因此在新代码中应直接使用JSONResponse。附加状态码与 OpenAPI / API 文档的关系如果你直接返回附加状态码和Response它们不会被包含在 OpenAPI schema即 API 文档中因为 FastAPI 没有办法提前知道你将要返回什么内容——它无法静态分析出代码分支中手动构造的JSONResponse及其状态码。但这并不意味着无法文档化你可以使用Additional Responses附加响应机制在代码中为这些额外的状态码声明对应的响应模型与描述使其出现在 OpenAPI 与交互式文档中。FastAPI 官方进阶文档《Additional Responses》专门讲解了这一主题。两种机制的定位总结如下场景推荐做法运行时返回非主状态码的响应体直接返回JSONResponse(status_code..., content...)让附加状态码出现在 OpenAPI/API 文档中在路径操作装饰器中使用responses参数声明附加响应两者可以组合使用运行时用JSONResponse返回实际数据装饰器中用responses声明文档实现行为与文档兼备。小结一个路径操作的主状态码通过装饰器status_code或默认值确定需要在同一端点返回附加状态码时直接返回JSONResponse等Response对象并设置status_code即可这是官方推荐且最直接的方式直接返回的Response不经过模型序列化请自行确保content是合法 JSON 且包含所需数据手动返回的附加状态码不会自动进入 OpenAPI schema如需文档化请配合responses参数声明附加响应本教程对应源码位于 docs_src/additional_status_codes/测试位于 tests/test_tutorial/test_additional_status_codes/可用于对照学习与验证。【免费下载链接】fastapiFastAPI framework, high performance, easy to learn, fast to code, ready for production项目地址: https://gitcode.com/GitHub_Trending/fa/fastapi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考