首页
/ FastAPI 路径操作配置详解:用装饰器参数声明状态码、标签与接口元数据

FastAPI 路径操作配置详解:用装饰器参数声明状态码、标签与接口元数据

2026-09-06 18:36:34作者:俞予舒Fleming

路径操作配置(Path Operation Configuration)是 FastAPI 用来自动生成 OpenAPI 文档与交互式 API 界面的关键机制。本文将聚焦于在 @app.get()@app.post()路径操作装饰器上直接传入的 status_codetagssummarydescriptionresponse_descriptiondeprecated 等参数,逐一结合本仓库中的示例代码与源码实现,说明这些参数如何被写入 OpenAPI schema、如何影响 Swagger UI 的展示效果,帮助你为自己的接口声明准确、完整且可维护的元数据。

参数传给装饰器,而不是传给函数

使用这些配置参数前,必须牢记一个重要的前提:它们全部是装饰器的参数,与路径操作函数(async def / def)本身的入参毫无关系。也就是说,它们描述的是“这个 HTTP 接口长什么样”,而不是“接口如何接收请求数据”。

@app.post("/items/", status_code=status.HTTP_201_CREATED)  # 传给装饰器
async def create_item(item: Item) -> Item:  # 括号里是函数自身的参数
    return item

从源码结构看,FastAPI 在注册路由时会把装饰器收到的这些元数据原样保存到路由对象 APIRoute 上(见 fastapi/routing.py),后续生成 OpenAPI 时再逐项取出。本文后续每个小节,都会把“装饰器参数 → 路由对象 → OpenAPI 字段 → 文档界面效果”这条链路讲透。

设置响应状态码:status_code

status_code 可以显式声明路径操作返回的 HTTP 状态码。它有两个作用:一是实际响应会带上该状态码,二是它会写入 OpenAPI schema,成为文档中该响应的标识。

直接传整数,或使用 status 常量

可以直接传 int,例如 404;但如果记不住每个数字的含义,更推荐使用 status 模块里语义化命名的常量:

from fastapi import FastAPI, status
from pydantic import BaseModel

app = FastAPI()


class Item(BaseModel):
    name: str
    description: str | None = None
    price: float
    tax: float | None = None
    tags: set[str] = set()


@app.post("/items/", status_code=status.HTTP_201_CREATED)
async def create_item(item: Item) -> Item:
    return item

上面的完整示例位于 docs_src/path_operation_configuration/tutorial001_py310.py,含义是“创建成功后返回 201 Created”,语义一目了然。常见的常量还包括 status.HTTP_200_OKstatus.HTTP_204_NO_CONTENTstatus.HTTP_400_BAD_REQUESTstatus.HTTP_404_NOT_FOUNDstatus.HTTP_500_INTERNAL_SERVER_ERROR 等,均可直接使用。

技术细节:fastapi.status 就是 Starlette 的 status

你也可以写 from starlette import status。事实上,FastAPI 提供的 fastapi.statusstarlette.status 是同一个东西——前者只是为开发者提供的便捷导出,常量本身来自 Starlette。

源码层面还有一个容易被忽略的细节:在路由注册时,若传入的状态码是 IntEnum(例如某些常量以枚举形式定义),FastAPI 会先通过 int() 将其转换为普通整数再保存(见 fastapi/routing.py);若没有显式传入 status_code,生成 OpenAPI 时则会从默认响应类的 status_code 默认值中推导(通常为 200,对应逻辑在 fastapi/openapi/utils.py)。

tags 为接口分组

当接口数量增多,把相关路径操作归入同一“标签”会让文档结构清晰很多。给路径操作传 tags,参数类型是 list[str](通常只放一个字符串):

from 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: set[str] = set()


@app.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"}]

完整示例见 docs_src/path_operation_configuration/tutorial002_py310.py。三个接口分别归属 itemsusers 两个标签。标签会被加入 OpenAPI schema,并由自动文档界面用于分组展示——在 Swagger UI 中,属于 items 的接口会折叠在 items 分组下、属于 users 的接口折叠在 users 分组下:

FastAPI Swagger UI 中接口按照 items 与 users 标签分组展示的效果

从源码看,生成 OpenAPI 时只要路由上有 tagsget_openapi_operation_metadata() 就会直接把它写入 operation["tags"](见 fastapi/openapi/utils.py)。

Enum 统一管理标签

在大型应用里,标签会越积越多,而且很容易出现“同一个分组用词不一致”的情况(比如有时写 items、有时写 item)。此时把标签放进一个 Enum 集中管理是更稳妥的做法——FastAPI 对枚举标签的支持与纯字符串完全一致

from enum import Enum

from fastapi import FastAPI

app = FastAPI()


class Tags(Enum):
    items = "items"
    users = "users"


@app.get("/items/", tags=[Tags.items])
async def get_items():
    return ["Portal gun", "Plumbus"]


@app.get("/users/", tags=[Tags.users])
async def read_users():
    return ["Rick", "Morty"]

完整示例见 docs_src/path_operation_configuration/tutorial002b_py310.py。将 Tags 集中定义后,每个路径操作都引用 Tags.itemsTags.users 这样的成员,彻底避免手写字符串造成的拼写漂移。枚举成员的 value(此处即字符串 "items""users")最终会出现在 OpenAPI 与文档界面中,保证分组名全局唯一、始终一致。

声明接口的 summarydescription

summary 是显示在文档中的接口短标题,description 则是更详细的说明文字。两者都可以直接作为装饰器参数传入:

from 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: set[str] = set()


@app.post(
    "/items/",
    summary="Create an item",
    description="Create an item with all the information, name, description, price, tax and a set of unique tags",
)
async def create_item(item: Item) -> Item:
    return item

完整示例见 docs_src/path_operation_configuration/tutorial003_py310.py

源码里对 summary 还有一个“兜底”行为值得了解:如果未显式提供,OpenAPI 的 summary 会由路由对象的函数名推导生成——将函数名中的下划线替换为空格并转为标题格式(generate_operation_summary() 的逻辑见 fastapi/openapi/utils.py)。也就是说,好的函数命名(如 create_item)即使不写 summary,也能得到尚可阅读的默认标题;但为了对外 API 文档的准确性,仍建议显式声明。

用函数 docstring 书写多行 Markdown 描述

description 往往很长、需要跨多行。为此 FastAPI 提供了更顺手的写法:直接把多行说明写进路径操作函数的 docstring,FastAPI 会自动把它读取为接口描述。docstring 支持 Markdown 语法,会按 Markdown 渲染展示,且能正确处理 docstring 缩进:

from 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: set[str] = set()


@app.post("/items/", summary="Create an item")
async def create_item(item: Item) -> Item:
    """
    Create an item with all the information:

    - **name**: each item must have a name
    - **description**: a long description
    - **price**: required
    - **tax**: if the item doesn't have tax, you can omit this
    - **tags**: a set of unique tag strings for this item
    """
    return item

完整示例见 docs_src/path_operation_configuration/tutorial004_py310.py

源码实现里这一步发生在路由构造阶段:如果装饰器没有显式提供 description,FastAPI 会用 inspect.cleandoc() 处理函数 docstring(自动去除统一的缩进、清理首尾空行)作为描述,随后再进一步裁剪内容(见 fastapi/routing.py)。正因如此,docstring 内部的 Markdown 列表、粗体等格式都能被保留并正确渲染:

展开后的 POST /items/ 接口在 Swagger UI 中显示来自 docstring 的 Markdown 描述与请求参数

顺带提醒:docstring 描述也会进入 OpenAPI schema 的 description 字段,因此同样会展示在 ReDoc 等其他遵循该规范的文档工具中。

response_description 描述响应本身

response_description 用于描述响应。它和 description 的区别要分清:

  • description:描述整个路径操作(接口是做什么的、怎么用);
  • response_description:只描述响应(成功时返回什么内容)。
from 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: set[str] = set()


@app.post(
    "/items/",
    summary="Create an item",
    response_description="The created item",
)
async def create_item(item: Item) -> Item:
    """
    Create an item with all the information:

    - **name**: each item must have a name
    - **description**: a long description
    - **price**: required
    - **tax**: if the item doesn't have tax, you can omit this
    - **tags**: a set of unique tag strings for this item
    """
    return item

完整示例见 docs_src/path_operation_configuration/tutorial005_py310.py

这里有一个重要的“隐含约定”:OpenAPI 规范要求每个路径操作都必须给出响应描述。因此,如果你没有提供 response_description,FastAPI 会自动生成默认值 "Successful response"。这一点从路由对象的初始化可以确认——response_description 的默认值即 "Successful Response"(见 fastapi/routing.py),而在生成 OpenAPI 响应时,它会被写入 responses[<状态码>]["description"](见 fastapi/openapi/utils.py)。想为文档提供更有信息量的语义,就应像示例那样主动传参,而不是依赖默认文案。

标记 deprecated,优雅地废弃旧接口

当某个接口已过时、又不希望立即删除时(例如仍被老客户端调用),可以用 deprecated=True 把它标记为“已弃用”:

from fastapi import FastAPI

app = FastAPI()


@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"}]


@app.get("/elements/", tags=["items"], deprecated=True)
async def read_elements():
    return [{"item_id": "Foo"}]

完整示例见 docs_src/path_operation_configuration/tutorial006_py310.py。被标记后,文档界面上该接口会明确呈现“Deprecated”状态——通常表现为整块变灰并带 Warning: Deprecated 提示:

Swagger UI 中被标记为 deprecated 的 GET /elements/ 接口整块置灰并显示 Deprecated 提示

把被弃用的 GET /elements/ 与正常的 GET /items/ 并列查看时,对比尤其明显:正常接口颜色饱满、可正常展开调用,弃用接口则整体灰化。与此同时,源码中 route.deprecated 会被映射为 OpenAPI 的 operation["deprecated"] 字段(见 fastapi/openapi/utils.py),因此该信息不只是界面装饰,而是被正式写进 schema,客户端代码生成器等工具也能据此感知接口的废弃状态。

小结与验证方式

把装饰器级元数据配置组合起来,一个信息完备的路径操作大致会长这样:

@app.post(
    "/items/",
    tags=[Tags.items],
    summary="Create an item",
    response_description="The created item",
    status_code=status.HTTP_201_CREATED,
    deprecated=False,
)
async def create_item(item: Item) -> Item: ...
  • status_code:声明响应状态码,会作用于实际响应并被写入 OpenAPI;
  • tags / tags + Enum:统一为接口分组,驱动交互式文档的折叠结构;
  • summarydescription(或函数 docstring):定义接口的标题与完整说明;
  • response_description:单独描述响应语义,缺省时 FastAPI 自动填充 "Successful response"
  • deprecated:把旧接口标记为废弃而不删除,文档与 schema 同步呈现。

所有配置都是“纯声明式”的——你只需把这些参数传给路径操作装饰器,FastAPI 就会负责把它们落到实际 HTTP 响应与自动生成的 OpenAPI schema(/openapi.json)中,并在 Swagger UI(/docs)与 ReDoc(/redoc)里正确呈现。

如果你想把上述参数的字段级细节进一步打磨(例如手动覆盖 OpenAPI 中的 operationIddeprecated 之类的字段),仓库还提供了进阶主题 path_operation_advanced_configuration 与全局元数据 metadata 的对应示例可供继续阅读。对本文六个示例,本仓库的 tests/test_tutorial/test_path_operation_configurations/ 目录下提供了 test_tutorial001.pytest_tutorial006.py(含 test_tutorial002b.py、合并了 003/004 的 test_tutorial003_tutorial004.py)等一一对应的测试用例,你可以通过运行这些测试直接验证各项配置在真实路由与 OpenAPI 输出中的行为是否符合预期。

登录后查看全文
热门项目推荐
相关项目推荐