1.路由与请求参数校验

18 阅读4分钟

一、 路由基础与 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 BaseModelPOST / 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
  • 优势与对比:

    • 相比传统开发中统一使用 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 内部。