一、 路由基础与 async/def 调度
1. 路由四大要素
@app.get("/")
async def root():
return {"message": "hello world"}
app:FastAPI 实例对象,全局路由注册中心。.get():HTTP 请求方法(GET/POST/PUT/DELETE/PATCH)。"/":请求路径 (Endpoint Path)。async def root():视图函数,返回值会被 FastAPI 自动序列化为 JSON。
2. async def 与 def 的调度区别
async def:运行在主事件循环中,适合内部带有await的非阻塞 I/O。def:被 FastAPI 自动放入外部线程池 (ThreadPool) 运行,防止同步阻塞主事件循环。
二、 请求参数的三大分类与校验
1. 参数分类速查
| 参数类型 | 识别规则 / 声明方式 | 常见 HTTP 方法 | 作用说明 |
|---|---|---|---|
| 路径参数 (Path) | 声明在路由路径的大括号中(如 /items/{item_id}) | GET / DELETE | 唯一定位特定资源 |
| 查询参数 (Query) | 未在路径中声明的基础类型参数(如 q: str) | GET | 数据的过滤、排序、分页等 |
| 请求体 (Body) | 声明类型继承自 Pydantic BaseModel | POST / PUT / PATCH | 传输复杂的 JSON 结构化数据 |
2. 路径参数 Path(...) 高级校验
用于对路径参数做数值范围或字符串长度限制,导入 from fastapi import Path。
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/book/{id}")
def get_book(
# ... 表示必填;ge=1 表示 >=1;le=1000 表示 <=1000
id: int = Path(..., ge=1, le=1000, description="书籍ID,范围 1~1000")
):
return {"id": id, "title": f"这是第 {id} 本书"}
- 拦截机制:传入非法值(如
/book/0),FastAPI 自动返回422 Unprocessable Entity。
3. 查询参数 Query(...) 默认值与分页
用于对 URL ? 后的参数设置默认值和限制,导入 from fastapi import Query。
from fastapi import FastAPI, Query
app = FastAPI()
@app.get("/news/list")
def get_news_list(
# default=0 设为选填;lt=100 限制必须小于 100
skip: int = Query(default=0, description="跳过记录数", lt=100),
limit: int = Query(default=10, description="返回记录数")
):
return {"skip": skip, "limit": limit}
4. 请求体 (Body) 与 Pydantic 字段声明三种写法
from fastapi import FastAPI
from pydantic import BaseModel, Field
app = FastAPI()
class Product(BaseModel):
# ① 必填字段:用 ... 占位,无默认值,客户端在 JSON 中必须传
name: str = Field(..., description="商品名称 (必填)")
# ② 带具体默认值的选填字段:指定 default=9.9,不传时自动使用 9.9
price: float = Field(default=9.9, gt=0, description="商品价格 (选填,默认 9.9)")
# ③ 允许为空的选填字段:使用 str | None 且 default=None,不传时自动为 None
description: str | None = Field(default=None, description="商品描述 (选填,默认 None)")
@app.post("/products")
def create_product(product: Product):
return {"message": "创建成功", "data": product}
Pydantic 字段“必填/选填”总结表
| 声明方式 | 示例语法 | 客户端是否必传 | 不传时的逻辑 |
|---|---|---|---|
| 必填字段 | name: str 或 Field(..., ...) | 必须传 | FastAPI 拦截并返回 422 报错 |
| 带默认值选填 | price: float = 9.9 或 Field(default=9.9) | 选填 | 自动赋予指定默认值 (9.9) |
| 允许 None 选填 | description: str | None = None | 选填 | 自动赋予 None |
Python 3.10+ 管道符
|说明:str | None = None是 Python 3.10+ 原生语法,用来替代旧版的Optional[str] = None,代表“类型可以是字符串或 None,默认值为 None”。
请求参数 自己的理解
1. 路径参数 (Path Parameters)
-
核心作用:用于定位唯一的资源。
-
位置与形态:直接拼在 URL 路径本身(位于问号
?前面),作为 URL 路径的一部分。 -
现代 RESTful 风格示例:
- 获取 ID 为 42 的用户资料:
GET /users/42 - 删除 ID 为 42 的用户:
DELETE /users/42
- 获取 ID 为 42 的用户资料:
-
优势与对比:
- 相比传统开发中统一使用
POST拼接getUserInfo?id=42或deleteUserInfo?id=42的写法,现代 RESTful 风格通过 HTTP 方法区分动作,使得 URL 表达极其清晰,大大减少了冗余的 API 接口定义。 - 在传统开发模式中路径参数使用相对较少,但在现代 Web 架构中已成为标准规范。
- 相比传统开发中统一使用
2. 查询参数 (Query Parameters)
- 核心作用:常用于数据筛选、分页、搜索与控制。
- 位置与形态:拼在 URL 问号
?后面,以键值对形式存在(如?page=1&size=20)。 - 使用场景:通常搭配
GET请求使用,在实际开发中使用频率极高(例如:GET /data?id=42)。
3. 请求体参数 (Body Parameters / Payload)
- 核心作用:用于传输结构复杂、数据量大或包含敏感信息的 Payload 数据。
- 位置与形态:不暴露在 URL 中,而是放在 HTTP 请求体 (Request Body) 中传输。
- 使用场景:通常搭配非
GET请求(如POST、PUT)使用,将复杂的 JSON 结构置于 Payload 内部。