FastAPI 教程

FastAPI 路径参数

在 FastAPI 中,路径参数(Path Parameters) 是 URL 路径中动态变化的部分。它们通常用于标识特定的资源(例如:获取 ID 为 5 的商品 /items/5)。

FastAPI 对路径参数的处理非常智能,不仅能自动提取数据,还能自动进行类型转换和验证

以下是路径参数的核心用法和进阶技巧:


1. 基础用法:声明与自动类型转换

你只需要在路径装饰器中使用 {} 声明变量名,并在函数参数中声明相同的变量名Python 类型。FastAPI 会自动将 URL 中的字符串转换为你声明的类型。

纯文本
plaintext
from fastapi import FastAPI

app = FastAPI()

# URL: /items/42
@app.get("/items/{item_id}")
async def read_item(item_id: int):
    # FastAPI 会自动将 "42" 转换为整数 42
    # 如果传入 "/items/foo",FastAPI 会自动返回清晰的 422 验证错误
    return {"item_id": item_id, "type": type(item_id).__name__}

2. 支持的常见数据类型

除了 strint,FastAPI 原生支持多种类型的自动解析:

纯文本
plaintext
import uuid
from fastapi import FastAPI

app = FastAPI()

# 1. 浮点数: /floats/3.14
@app.get("/floats/{value}")
async def read_float(value: float):
    return {"value": value}

# 2. 布尔值: /bools/true 或 /bools/1 (不区分大小写)
@app.get("/bools/{value}")
async def read_bool(value: bool):
    return {"value": value}

# 3. UUID: /uuids/123e4567-e89b-12d3-a456-426614174000
@app.get("/uuids/{value}")
async def read_uuid(value: uuid.UUID):
    return {"value": str(value)}

3. 路径参数验证 (使用 Path)

如果你想对路径参数添加额外的验证规则(如最小值、最大值、正则表达式),可以使用 fastapi.Path
(推荐使用 Annotated 语法,将验证逻辑与类型提示分离)

纯文本
plaintext
from typing import Annotated
from fastapi import FastAPI, Path

app = FastAPI()

@app.get("/items/{item_id}")
async def read_item(
    item_id: Annotated[
        int, 
        Path(
            title="The ID of the item to get",
            description="Item ID must be greater than 0",
            ge=1,          # Greater than or equal to 1
            le=1000        # Less than or equal to  it 1000
        )
    ]
):
    return {"item_id": item_id}

如果请求 /items/0/items/2000,FastAPI 会返回 422 错误,并附带你在 Path 中写的描述信息。


4. 预定义值 (使用 Enum)

如果你希望路径参数只能是几个特定的值(例如:模型名称、状态),可以使用 Python 标准的 Enum 类。这不仅限制了输入,还会在 Swagger UI (/docs) 中生成下拉选择框。

纯文本
plaintext
from enum import Enum
from fastapi import FastAPI

class ModelName(str, Enum):
    alexnet = "alexnet"
    resnet = "resnet"
    lenet = "lenet"

app = FastAPI()

@app.get("/models/{model_name}")
async def get_model(model_name: ModelName):
    if model_name == ModelName.alexnet:
        return {"model_name": model_name, "message": "Deep Learning FTW!"}

    # 可以通过 .value 获取字符串值
    return {"model_name": model_name, "message": "Have some residuals"}

如果请求 /models/unknown,FastAPI 会返回 422 错误,提示该值不在允许的枚举列表中。

has a special meaning in URLs. By default, a path parameter will not match slashes /.

5. 包含路径的路径参数 (Path Converters)

如果你需要捕获包含斜杠的路径(例如:文件路径 /files/users/config.txt),你需要使用特殊的路径转换器 :path

纯文本
plaintext
from typing import Annotated
from fastapi import FastAPI, Path

app = FastAPI()

# 注意 {file_path:path} 中的 :path
@app.get("/files/{file_path:path}")
async def read_file(
    file_path: Annotated[str, Path(description="The full file path")]
):
    return {"file_path": file_path}

请求 /files/users/config.txt 时,file_path 的值将是 "users/config.txt"


6. ⚠️ 路径声明顺序 (重要陷阱)

FastAPI 是按照代码中从上到下的顺序来匹配路径的。如果你有一个动态路径和一个固定路径,必须将固定路径放在前面

纯文本
plaintext
from fastapi import FastAPI

app = FastAPI()

# ✅ 正确:固定路径在前
@app.get("/users/me")
async def read_user_me():
    return {"user_id": "the current user"}

# 动态路径在后
@app.get("/users/{user_id}")
async def read_user(user_id: str):
    return {"user_id": user_id}

如果反过来写,请求 /users/me 时,FastAPI 会匹配到 /users/{user_id},并将 user_id 解析为字符串 "me",导致逻辑错误。


7. 多个路径参数

你可以同时使用多个路径参数,FastAPI 会按名称一一对应。

纯文本
plaintext
from fastapi import FastAPI

app = FastAPI()

@app.get("/users/{user_id}/items/{item_id}")
async def read_user_item(user_id: int, item_id: str):
    return {"user_id": user_id, "item_id": item_id}

总结:路径参数最佳实践

  1. 始终声明类型:不要只写 item_id,要写 item_id: int,让 FastAPI 帮你做验证。
  2. 优先使用 Annotated + Path:这是现代 FastAPI 的标准写法,代码更整洁,且对 IDE 和类型检查器更友好。
  3. 注意路由顺序:具体的、固定的路由永远放在通用的、动态的路由之前。

你想继续了解 查询参数 (Query Parameters),还是想看看如何将路径参数与 数据库查询 (如 SQLAlchemy) 结合起来?

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注