「FastAPI & SQLAlchemy 实战」系列共 10 篇,从协程基础讲到数据库接口。这是第 6 篇。
结论:路径里的 {name} 是路径参数,其余函数参数默认是查询参数;类型注解决定转换和校验,类型不对 FastAPI 自动返回 422。
一、路径参数:自动转换类型
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
访问 /items/3,函数收到的是 int 3,不是字符串 "3";访问 /items/foo 返回 422,因为 foo 不能转成 int。
二、路由顺序:具体路径放前面
@app.get("/users/me")
async def read_me():
return {"user_id": "current"}
@app.get("/users/{user_id}")
async def read_user(user_id: str):
return {"user_id": user_id}
如果 /users/{user_id} 写在前面,访问 /users/me 会被它匹配,user_id 变成 "me"。
三、查询参数:函数里没有路径的参数
items = [{"item1": "Foo"}, {"item2": "Bar"}, {"item3": "Baz"}]
@app.get("/items/")
async def read_items(start: int = 0, limit: int = 10):
return items[start:start + limit]
请求 /items/?start=0&limit=2,FastAPI 把字符串转成 int;不传就用默认值。
四、可选、必选与布尔转换
@app.get("/items/{item_id}")
async def read_item(
item_id: str,
q: str | None = None, # 可选,默认 None
short: bool = False, # 可选,自动转 bool
required: str = ..., # 必选查询参数
):
...
- 默认值
None:参数可选; - 不写默认值:参数必选,不传返回 422;
bool接受1/0、true/false、on/off、yes/no(大小写不敏感),其他值直接 422。
五、多个路径参数和查询参数
@app.get("/users/{user_id}/items/{item_id}")
async def read_user_item(
user_id: int,
item_id: str,
q: str | None = None,
short: bool = False,
):
return {"user_id": user_id, "item_id": item_id, "q": q, "short": short}
FastAPI 按参数名匹配,查询参数的声明顺序不重要。
六、验证
curl -s "http://127.0.0.1:8000/items/?start=0&limit=2"
curl -s "http://127.0.0.1:8000/items/foo" # 422
curl -s "http://127.0.0.1:8000/users/me"
curl -s "http://127.0.0.1:8000/users/100/items/500?short=yes"
七、常见错误
- 路径参数和函数参数名不一致:会变成必选查询参数;
- 路由顺序写反:
/users/me被/users/{user_id}吃掉; - 用字符串接收整数:失去类型校验,后面还要手动转换;
- 以为查询参数是必选:不写默认值才是必选。
下一篇
下一篇讲请求体:用 Pydantic 模型接收 JSON,再用 APIRouter 把路由拆到多个文件。

AI项目博客






