FastAPI 中,客户端向服务端传递数据主要通过两种参数:路径参数(Path Parameters)和查询参数(Query Parameters)。路径参数是 URL 路径的一部分,通常用于标识资源;查询参数跟在 ? 后面,常用于过滤、排序等可选条件。下面逐一讲解。

路径参数

路径参数写在 URL 路径中,使用 {} 占位,函数参数名与之对应即可。

基本用法

1
2
3
4
5
6
7
from fastapi import FastAPI

app = FastAPI()

@app.get("/users/{user_id}")
async def get_user(user_id: int):
return {"user_id": user_id}

访问 /users/42 时,user_id 会自动转为 int 类型。如果传入非数字如 /users/abc,FastAPI 会自动返回 422 校验错误。

类型校验

FastAPI 会根据类型注解自动做类型转换和校验:

1
2
3
4
@app.get("/items/{item_id}")
async def get_item(item_id: int):
# item_id 一定是个 int,否则直接返回 422
return {"item_id": item_id, "type": type(item_id).__name__}

支持的类型包括 intfloatstrboolUUID 等。

路径参数的顺序

注意:固定路径必须定义在动态路径之前,否则会被动态路径拦截:

1
2
3
4
5
6
7
8
9
10
# ✅ 正确:固定路径在前
@app.get("/users/me")
async def get_current_user():
return {"username": "admin"}

@app.get("/users/{user_id}")
async def get_user(user_id: int):
return {"user_id": user_id}

# ❌ 错误:如果 /users/{user_id} 在前,访问 /users/me 时 "me" 会被当成 user_id

使用 Path 做额外校验

1
2
3
4
5
6
7
8
9
10
11
12
13
from fastapi import Path

@app.get("/articles/{article_id}")
async def get_article(
article_id: int = Path(
..., # ... 表示必填
title="文章ID",
description="要获取的文章编号",
ge=1, # >= 1
le=10000, # <= 10000
)
):
return {"article_id": article_id}

Path 常用校验参数:

参数 说明
... 必填(省略号)
ge / gt 大于等于 / 大于
le / lt 小于等于 / 小于
min_length / max_length 字符串最小/最大长度
regex 正则匹配(FastAPI 旧版)
pattern 正则匹配(Pydantic v2)
title / description 文档展示用

枚举类型的路径参数

1
2
3
4
5
6
7
8
9
10
11
from enum import Enum

class CategoryEnum(str, Enum):
tech = "tech"
life = "life"
travel = "travel"

@app.get("/posts/{category}")
async def get_posts(category: CategoryEnum):
# 自动生成文档,且只接受这三个值
return {"category": category}

访问 /posts/tech 正常返回;访问 /posts/music 返回 422。


查询参数

查询参数是 URL 中 ? 后面的键值对,如 ?page=1&size=20。FastAPI 中,函数参数不在路径中且不是 Body 类型,就会被自动识别为查询参数

基本用法

1
2
3
@app.get("/posts")
async def list_posts(page: int = 1, size: int = 10):
return {"page": page, "size": size}

访问 /posts?page=2&size=5page=2, size=5;不传参数则使用默认值。

可选查询参数

1
2
3
4
5
6
7
8
9
10
11
from typing import Optional

@app.get("/search")
async def search(
keyword: Optional[str] = None,
category: Optional[str] = None,
):
result = {"keyword": keyword, "category": category}
if keyword:
result["match"] = f"搜索: {keyword}"
return result

Optional[str] = None 表示该参数可选,不传时为 None

使用 Query 做额外校验

1
2
3
4
5
6
7
8
9
from fastapi import Query

@app.get("/items")
async def list_items(
offset: int = Query(default=0, ge=0, description="偏移量"),
limit: int = Query(default=10, ge=1, le=100, description="每页数量"),
sort: Optional[str] = Query(default=None, pattern=r"^(asc|desc)$", description="排序方式"),
):
return {"offset": offset, "limit": limit, "sort": sort}

Query 支持与 Path 几乎相同的校验参数。

接收多个同名查询参数

1
2
3
4
5
6
7
8
9
from typing import List

@app.get("/filter")
async def filter_items(tags: List[str] = Query(default=[])):
"""
示例: /filter?tags=python&tags=fastapi&tags=web
结果: tags = ["python", "fastapi", "web"]
"""
return {"tags": tags}

布尔类型查询参数

1
2
3
4
5
6
7
8
9
10
@app.get("/products")
async def list_products(in_stock: bool = False):
"""
访问: /products?in_stock=true → True
/products?in_stock=1 → True
/products?in_stock=yes → True
/products?in_stock=on → True
/products → False(默认值)
"""
return {"in_stock": in_stock}

路径参数与查询参数的组合

最常见的场景是路径参数标识资源,查询参数做筛选:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@app.get("/users/{user_id}/posts")
async def get_user_posts(
user_id: int = Path(..., ge=1),
page: int = Query(default=1, ge=1),
size: int = Query(default=20, ge=1, le=100),
status: Optional[str] = Query(default=None, pattern=r"^(draft|published|archived)$"),
):
"""
获取某个用户的文章列表

- **user_id**: 用户ID(路径参数)
- **page**: 页码(查询参数,默认第1页)
- **size**: 每页数量(查询参数,默认20,最大100)
- **status**: 文章状态过滤(可选)
"""
return {
"user_id": user_id,
"page": page,
"size": size,
"status": status,
}

请求示例:/users/42/posts?page=2&size=5&status=published


小结

特性 路径参数 查询参数
位置 URL 路径中 /users/{id} URL ? 后面 ?key=val
用途 标识资源 过滤、排序、分页
必填 默认必填 默认可选
校验工具 Path() Query()
类型 str / int / UUID / Enum str / int / bool / List 等

掌握路径参数和查询参数是 FastAPI 开发的基础,配合 PathQuery 的校验能力,可以在不写额外逻辑的情况下完成大部分参数校验工作,并自动生成清晰的 API 文档。