Python Web 开发:FastAPI 路由装饰器与路径参数应用
???? 目录
- ???? FastAPI 路由装饰器:功能与使用
- ???? 动态路径参数:灵活处理 URL 路径
- ???? 路由参数验证:类型检查与正则表达式
???? FastAPI 路由装饰器:功能与使用
在 FastAPI 中,路由装饰器是 Web 应用中最常用的工具之一。通过路由装饰器,我们可以将 HTTP 请求方法(如 GET
、POST
、PUT
、DELETE
等)与对应的 Python 函数进行绑定,创建 API 路由。这些装饰器让 API 开发变得简单、高效,并且让代码更加简洁可读。常见的 FastAPI 路由装饰器包括 @app.get
、@app.post
等,分别用于处理 GET 请求和 POST 请求。
路由装饰器基础
FastAPI 的路由装饰器与传统的 Web 框架(如 Flask)类似,主要用于将客户端的 HTTP 请求映射到相应的处理函数。例如,一个简单的 GET 请求处理可以这样实现:
from fastapi import FastAPI
app = FastAPI()
@app.get("/hello")
async def read_hello():
return {"message": "Hello, World!"}
在这个例子中,@app.get("/hello")
就是一个路由装饰器,它将 HTTP GET 请求 /hello
映射到 read_hello
处理函数。当客户端向该路由发送 GET 请求时,FastAPI 会自动调用 read_hello
函数并返回相应的 JSON 数据。
支持多种 HTTP 方法
除了 @app.get
,FastAPI 还支持其他常见的 HTTP 请求方法,例如 POST
、PUT
、DELETE
等。每种 HTTP 方法对应一个装饰器。以下是不同请求方法的示例:
- POST 请求:用于创建资源,通常发送数据到服务器。
@app.post("/items")
async def create_item(item: dict):
return {"message": "Item created successfully", "item": item}
- PUT 请求:用于更新资源,通常更新现有的数据。
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: dict):
return {"message": "Item updated successfully", "item_id": item_id, "item": item}
- DELETE 请求:用于删除资源。
@app.delete("/items/{item_id}")
async def delete_item(item_id: int):
return {"message": f"Item {item_id} deleted successfully"}
通过不同的装饰器,FastAPI 可以方便地处理各种 HTTP 请求。开发者只需要关注业务逻辑的实现,框架会自动处理请求和响应。
支持其他功能的装饰器
FastAPI 的路由装饰器不仅支持常见的 HTTP 方法,还支持一些附加功能。例如,可以指定请求的响应模型、设置请求体和查询参数等:
from pydantic import BaseModel
class Item(BaseModel):
name: str
price: float
@app.post("/items", response_model=Item)
async def create_item(item: Item):
return item
在这个例子中,response_model=Item
用于指定返回数据的模型,这样 FastAPI 就会自动根据 Item
模型进行数据验证和序列化,确保返回的 JSON 数据符合预期。
???? 动态路径参数:灵活处理 URL 路径
在 Web 开发中,动态路径参数通常用于标识特定的资源,如通过 ID 查询某个特定用户的信息。FastAPI 提供了非常直观且易于使用的方式来处理动态路径参数。这些参数可以直接从 URL 中提取,并作为函数参数传递给路由处理函数。
使用动态路径参数
在 FastAPI 中,动态路径参数通过在路径中使用花括号 {}
来定义。例如,以下代码展示了如何通过动态路径参数获取用户的 ID:
@app.get("/users/{user_id}")
async def read_user(user_id: int):
return {"user_id": user_id, "name": "John Doe"}
在这个例子中,{user_id}
就是一个动态路径参数。当客户端访问 /users/123
时,FastAPI 会将 123
作为 user_id
参数传递给 read_user
函数,从而返回相应的用户信息。
动态路径参数的类型验证
FastAPI 支持为路径参数设置类型验证。例如,user_id
参数被指定为 int
类型,FastAPI 会自动检查传入的参数是否符合类型要求。如果请求的路径参数无法转换为整数,FastAPI 会自动返回 422 错误响应:
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id, "description": "This is a sample item"}
如果请求路径中的 item_id
不是一个有效的整数,FastAPI 会返回如下错误:
{
"detail": [
{
"loc": ["path", "item_id"],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]
}
使用多个动态路径参数
FastAPI 允许在路径中使用多个动态参数。这种方式特别适合于需要通过多个标识符进行访问的场景,例如通过用户 ID 和商品 ID 查询某个特定商品:
@app.get("/users/{user_id}/items/{item_id}")
async def read_item(user_id: int, item_id: int):
return {"user_id": user_id, "item_id": item_id, "item": "Sample Item"}
在这个例子中,user_id
和 item_id
都是动态路径参数。客户端可以通过访问 /users/123/items/456
来查询某个特定用户的商品信息。
???? 路由参数验证:类型检查与正则表达式
路由参数验证是 Web 开发中的一个重要方面。FastAPI 提供了强大的验证功能,可以在路径参数、查询参数、请求体等多个地方进行类型检查。通过这些验证,开发者可以确保 API 接收的数据是有效的,避免不必要的错误发生。
路由参数类型验证
FastAPI 自动支持对路径参数、查询参数等的类型验证。例如,如果你希望路径参数是一个字符串,FastAPI 会在运行时进行自动验证:
@app.get("/items/{item_id}")
async def read_item(item_id: str):
return {"item_id": item_id, "description": "This is a string item"}
在这个例子中,item_id
是一个字符串类型的路径参数。FastAPI 会自动验证请求路径中的 item_id
是否为有效的字符串类型。
使用正则表达式进行路径参数验证
除了简单的类型检查,FastAPI 还允许使用正则表达式对路径参数进行更复杂的验证。通过 Path
类,开发者可以为路径参数指定正则表达式,确保路径参数符合特定的格式。例如,假设你希望 item_id
参数仅包含数字并且长度为 5 位,可以这样写:
from fastapi import Path
@app.get("/items/{item_id}")
async def read_item(item_id: str = Path(..., regex=r"^\d{5}$")):
return {"item_id": item_id, "description": "Item ID is valid"}
在这个例子中,regex=r"^\d{5}$"
用于指定路径参数 item_id
必须是一个五位数字。如果请求的路径参数不符合正则表达式,FastAPI 会自动返回 422 错误。
路由参数的额外验证
除了类型验证和正则表达式,FastAPI 还支持更复杂的验证规则。例如,可以使用 Query
来验证查询参数:
from fastapi import Query
@app.get("/items/")
async def get_items(limit: int = Query(10, ge=1, le=100)):
return {"limit": limit}
在这个例子中,limit
查询参数被验证为一个介于 1 和 100 之间的整数。如果传入的查询参数不在这个范围内,FastAPI 会自动返回 422 错误。
自定义验证逻辑
如果内置的验证规则不能满足需求,FastAPI 还允许你定义自定义的验证逻辑。通过 Pydantic 模型和自定义验证器,开发者可以创建复杂的数据验证逻辑,并将其与路由参数一起使用。
from pydantic import BaseModel, validator
class Item(BaseModel):
name: str
price: float
@validator('price')
def check_price_positive(cls, v):
if v <= 0:
raise ValueError('Price must be positive')
return v
@app.post("/items/")
async def create_item(item: Item):
return item
在这个例子中,Item
模型定义了一个自定义验证器 check_price_positive
,确保商品的 price
始终为正数。如果请求的商品价格无效,FastAPI 会自动返回错误响应。