「FastAPI进阶指南」请求与响应模型全解析

「FastAPI进阶指南」请求与响应模型全解析

FastAPI作为基于Python的现代Web框架,凭借其高性能、自动文档生成和类型提示支持等特性,已成为构建RESTful API的首选工具。本文将围绕”请求与响应”这一核心主题,系统梳理FastAPI中路径参数、查询参数、请求体及响应模型的基础用法,结合实际开发场景提供可落地的解决方案。

一、路径参数:精准定位资源

路径参数是URL中用于标识特定资源的变量部分,在FastAPI中通过{参数名}语法定义。例如在用户管理系统中,/users/{user_id}路径中的user_id即为路径参数。

1.1 基础声明方式

  1. from fastapi import FastAPI
  2. app = FastAPI()
  3. @app.get("/users/{user_id}")
  4. async def read_user(user_id: int):
  5. return {"user_id": user_id}

上述代码展示了路径参数的基本声明:

  • 使用{user_id}在路径中定义参数位置
  • 通过类型注解int约束参数类型
  • FastAPI会自动将字符串路径参数转换为指定类型

1.2 路径参数转换规则

FastAPI内置了完善的类型转换机制:
| 类型注解 | 转换行为 | 示例 |
|————-|————-|———|
| int | 字符串转整数 | “/users/123” → 123 |
| float | 字符串转浮点数 | “/items/3.14” → 3.14 |
| bool | 字符串转布尔值 | “/enable/true” → True |
| str | 保持原样 | “/names/John” → “John” |

当类型不匹配时,FastAPI会自动返回422错误响应,例如访问/users/abc会触发验证失败。

1.3 路径参数命名约束

路径参数命名需遵循Python变量命名规范:

  • 只能包含字母、数字和下划线
  • 不能以数字开头
  • 推荐使用小写字母和下划线组合(如user_id

二、查询参数:灵活筛选数据

查询参数是URL中?后面的键值对,用于对资源进行筛选或排序。例如/users/?limit=10&skip=20包含两个查询参数。

2.1 基本查询参数

  1. @app.get("/items/")
  2. async def read_items(skip: int = 0, limit: int = 10):
  3. return {"skip": skip, "limit": limit}

关键特性:

  • 通过类型注解声明参数类型
  • 使用=设置默认值(可选参数)
  • 参数顺序不影响调用(/items/?limit=5&skip=10等效)

2.2 可选查询参数

  1. from typing import Optional
  2. @app.get("/users/{user_id}/items/")
  3. async def read_user_items(
  4. user_id: int,
  5. q: Optional[str] = None,
  6. short: bool = False
  7. ):
  8. items = f"DB查询用户{user_id}的物品"
  9. if q:
  10. items += f" 筛选条件: {q}"
  11. if short:
  12. return {"items": items[:50]}
  13. return {"items": items}

实际应用场景:

  • 搜索功能(q参数)
  • 响应格式控制(short参数)
  • 分页参数(pageper_page

2.3 查询参数验证

FastAPI支持Pydantic模型进行复杂验证:

  1. from pydantic import BaseModel, constr
  2. class QueryParams(BaseModel):
  3. q: Optional[constr(max_length=50)] = None
  4. limit: int = 100
  5. sort: Optional[str] = None
  6. @app.get("/search/")
  7. async def search(params: QueryParams):
  8. return {"params": params}

优势:

  • 集中管理查询参数
  • 内置字段验证(如字符串长度限制)
  • 自动生成API文档

三、请求体:结构化数据传输

当需要传输复杂数据时,请求体(Request Body)是更合适的选择。FastAPI通过Pydantic模型实现高效的请求体处理。

3.1 基础请求体

  1. from pydantic import BaseModel
  2. class Item(BaseModel):
  3. name: str
  4. description: Optional[str] = None
  5. price: float
  6. tax: Optional[float] = None
  7. @app.post("/items/")
  8. async def create_item(item: Item):
  9. item_dict = item.dict()
  10. if item.tax:
  11. price_with_tax = item.price + item.tax
  12. item_dict.update({"price_with_tax": price_with_tax})
  13. return item_dict

工作原理:

  1. 客户端发送JSON请求体
  2. FastAPI自动反序列化为Item对象
  3. 通过item.dict()转换为字典
  4. 支持嵌套模型和复杂验证

3.2 多请求体支持

FastAPI支持同时接收多个请求体参数:

  1. @app.put("/items/{item_id}")
  2. async def update_item(
  3. item_id: int,
  4. item: Item,
  5. user: User, # 假设存在User模型
  6. importance: int = Body(...)
  7. ):
  8. results = {
  9. "item_id": item_id,
  10. "item": item,
  11. "user": user,
  12. "importance": importance
  13. }
  14. return results

Body(...)语法表示该参数为必填项。

3.3 请求体验证

Pydantic模型提供强大的验证功能:

  1. from pydantic import EmailStr, HttpUrl, conint
  2. class UserIn(BaseModel):
  3. username: str
  4. email: EmailStr
  5. full_name: Optional[str] = None
  6. website: Optional[HttpUrl] = None
  7. age: conint(ge=0, le=120) = 18 # 0 ≤ age ≤ 120

验证规则示例:

  • EmailStr:自动验证邮箱格式
  • HttpUrl:验证URL有效性
  • conint:约束数值范围

四、响应模型:精准控制输出

响应模型决定了API返回的数据结构,FastAPI通过类型注解自动处理序列化。

4.1 基础响应模型

  1. @app.post("/items/", response_model=Item)
  2. async def create_item(item: Item):
  3. return item # 自动序列化为JSON

关键特性:

  • 使用response_model指定返回类型
  • 自动过滤未声明的字段
  • 支持嵌套模型

4.2 响应模型字段控制

  1. class ItemOut(BaseModel):
  2. name: str
  3. price: float
  4. # 不包含description和tax字段
  5. @app.post("/items/simple/", response_model=ItemOut)
  6. async def create_simple_item(item: Item):
  7. return item # 只返回ItemOut中声明的字段

应用场景:

  • 返回计算字段(如总价)
  • 隐藏敏感信息
  • 简化复杂对象

4.3 响应状态码与头部

  1. from fastapi import Response, status
  2. @app.post("/items/", response_model=Item, status_code=status.HTTP_201_CREATED)
  3. async def create_item(item: Item, response: Response):
  4. response.headers["X-Custom-Header"] = "Hello"
  5. return item

扩展功能:

  • 自定义HTTP状态码
  • 添加响应头部
  • 结合Pydantic模型使用

五、最佳实践总结

  1. 参数类型明确:始终为路径参数和查询参数添加类型注解
  2. 模型复用:创建共享的Pydantic模型减少代码重复
  3. 分页实现:推荐使用limit/offsetpage/per_page模式
  4. 版本控制:通过路径前缀(如/v1/)管理API版本
  5. 文档增强:利用OpenAPI注解补充API说明

六、性能优化建议

  1. 异步处理:对I/O密集型操作使用async def
  2. 数据验证前置:尽早验证请求数据减少无效处理
  3. 响应缓存:对静态响应考虑使用缓存中间件
  4. 模型扁平化:避免过深的嵌套模型影响序列化性能

通过系统掌握这些核心机制,开发者能够高效构建出稳定、可维护的FastAPI应用。实际开发中,建议结合Postman等工具进行API测试,同时利用FastAPI自动生成的交互式文档(访问/docs路径)提升开发效率。