(三)路径参数、查询参数与请求体
1. 先拆开一条请求
请求 /books/3 想找编号为 3 的书;请求 /books?finished=false&limit=2 想筛选未读书,最多返回两条。编号参与定位资源,筛选与数量放在问号后面。新增书的多个字段则一起放入 JSON 请求体。
| 输入位置 | 本章写法 | 取得的值 |
|---|---|---|
| 路径 | /books/{book_id} 与 book_id: int |
将对应路径段转换为整数 |
| 查询串 | finished: bool | None = None |
未提供时为 None,false 转为 False |
| 查询约束 | Annotated[int, Query(ge=1, le=100)] |
检查条数范围,错误时交回 422 |
| JSON 请求体 | data: BookCreate |
解析为字典后交给模型校验 |
| 原始请求对象 | request: Request |
取得应用状态、头等请求信息 |
Annotated 来自 typing。可以先把 Annotated[int, Query(...)] 分成两层:这个值的 Python 类型是 int,后面的 Query 告诉 FastAPI 去哪里取值、执行哪些检查。Path 同理对应路径参数,ge 是“大于等于”,le 是“小于等于”。它们给类型注解附上运行时规则。
2. 缺少值与具体值
finished=None 表示没有按状态筛选;finished=False 表示筛选未读书。代码使用 if finished is not None,所以 False 会进入筛选分支。若写成 if finished,请求 finished=false 时就会漏掉这个筛选动作。
查询串本来就是文本。框架按布尔规则把 false 等写法解释为布尔值;JSON 本身已经有 true 和 false,后面会要求书籍请求体使用真正的布尔值。两处输入经过的转换规则不同,观察的是同一件事:从 HTTP 文本得到业务需要的 Python 值。