路径参数(Path Parameters) 是 FastAPI 中最基础也最重要的概念之一。
🧩 一、什么是路径参数?
路径参数是从 URL 路径中提取的变量。
例如:
GET /users/123
GET /items/apple其中 123 和 apple 就是路径参数,分别代表用户 ID 和商品名称。
✅ 二、基本语法与示例
在 FastAPI 中,路径参数通过函数参数名与路径中的 {} 名称匹配。
🔹 示例 1:简单路径参数
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
def read_item(item_id: int):
return {"item_id": item_id}- 请求:
GET /items/42 - 响应:
{"item_id": 42} - FastAPI 会自动将
"42"转为int类型!
✅ 类型提示(Type Hint)会触发自动数据校验和转换!
🔹 示例 2:多个路径参数
@app.get("/users/{user_id}/orders/{order_id}")
def read_user_order(user_id: int, order_id: str):
return {"user_id": user_id, "order_id": order_id}- 请求:
GET /users/1001/orders/ORD-2025 - 响应:
{"user_id": 1001, "order_id": "ORD-2025"}
⚠️ 路径参数顺序不重要,名字必须和路径中的 {} 一致。🔹 示例 3:带类型校验(自动错误处理)
@app.get("/items/{item_id}")
def read_item(item_id: int):
return {"item_id": item_id}- 请求:
GET /items/abc 响应(自动返回 422 错误):
{ "detail": [ { "loc": ["path", "item_id"], "msg": "value is not a valid integer", "type": "type_error.integer" } ] }
✅ 无需手动写 try-except!FastAPI 自动做数据验证 + 错误响应。
⚠️ 三、重要注意事项(新手易错点)
1️⃣ 路径参数必须放在路径中,且用 {} 包裹
# ❌ 错误:没有 {},item_id 会被当作字面量
@app.get("/items/item_id")
# ✅ 正确
@app.get("/items/{item_id}")2️⃣ 函数参数名必须和 {} 中的名字完全一致
# ❌ 错误:名字不匹配
@app.get("/items/{item_id}")
def read_item(id: int): # 参数名是 id,不是 item_id
# ✅ 正确
def read_item(item_id: int):3️⃣ 路径匹配顺序很重要!更具体的路径要写在前面
# ❌ 危险:固定路径被当作路径参数
@app.get("/users/me")
def read_current_user():
return {"user": "current"}
@app.get("/users/{user_id}")
def read_user(user_id: str):
return {"user_id": user_id}✅ 正确顺序:固定路径放前面!
@app.get("/users/me") # 先匹配这个
def read_current_user():
return {"user": "current"}
@app.get("/users/{user_id}") # 再匹配这个
def read_user(user_id: str):
return {"user_id": user_id}否则,请求 /users/me 会被第二个路由捕获,user_id = "me",逻辑错误!
4️⃣ 路径参数默认是必需的(required)
- 不能省略,也不能设默认值(除非用查询参数)
- 如果需要可选,请改用 查询参数(Query Parameters)
# 路径参数不能有默认值 ❌
@app.get("/items/{item_id}")
def read_item(item_id: int = 0): # 不推荐!语义不清
# 应该用查询参数 ✅
@app.get("/items/")
def read_items(skip: int = 0, limit: int = 10):
...5️⃣ 支持任意类型(但需可从字符串转换)
FastAPI 使用 Pydantic 进行数据解析,支持:
| 类型 | 示例 |
|---|---|
int, float | 自动转数字 |
str | 默认类型 |
UUID | 自动校验格式 |
datetime | 支持 ISO 8601 格式 |
| 自定义类 | 需继承 BaseModel(一般用于请求体,非路径参数) |
from uuid import UUID
@app.get("/posts/{post_id}")
def read_post(post_id: UUID):
return {"post_id": str(post_id)}请求:GET /posts/12345678-1234-5678-1234-567812345678 → 成功
请求:GET /posts/invalid → 自动返回 422 错误
🧪 四、完整可运行示例
# main.py
from fastapi import FastAPI
from uuid import UUID
app = FastAPI()
@app.get("/")
def home():
return {"message": "Hello FastAPI!"}
@app.get("/users/me")
def read_current_user():
return {"user": "the current user"}
@app.get("/users/{user_id}")
def read_user(user_id: str):
return {"user_id": user_id}
@app.get("/items/{item_id}")
def read_item(item_id: int):
return {"item_id": item_id}
@app.get("/files/{file_path:path}")
def read_file(file_path: str):
return {"file_path": file_path}💡 最后一个例子用了 路径转换器(
:path),允许路径中包含/,比如:
- 请求:
GET /files/folder1/folder2/file.txtfile_path = "folder1/folder2/file.txt"