一、问题现象与本质分析
当使用FastAPI构建API接口时,"422 Unprocessable Entity"是最常见的HTTP状态码错误之一。该错误通常发生在以下场景:
- 请求体数据验证失败:POST/PUT请求中包含不符合Pydantic模型定义的字段
- 数据类型不匹配:例如将字符串传递给期望整数的字段
- 缺失必填字段:未提供标记为required的字段值
- 自定义验证器触发:Field或validator装饰器中定义的校验规则未通过
二、深度解决方案
1. 检查请求内容结构
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
tax: float = None # 可选字段
@app.post("/items/")
async def create_item(item: Item):
return item
常见错误:发送{"name": "Foo"}时会报422,因为缺少必填的price字段。
2. 使用try-except捕获验证异常
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc):
return JSONResponse(
status_code=400,
content={"detail": exc.errors(), "body": exc.body},
)
3. 配置自定义错误消息
在Pydantic模型中使用Field的error_messages参数:
from pydantic import Field
class User(BaseModel):
age: int = Field(..., gt=0,
error_messages={
"gt": "年龄必须大于0",
"type": "必须是整数"
})
三、高级调试技巧
- 启用调试模式:
app = FastAPI(debug=True) - 使用HTTPie测试:
http POST :8000/items/ name="Foo" price=invalid - 分析错误详情:422响应会包含详细的错误定位信息
四、预防性编程实践
| 问题类型 | 预防措施 |
|---|---|
| 数据类型错误 | 使用mypy进行静态类型检查 |
| 字段缺失 | 编写完整的API文档示例 |
| 复杂验证 | 添加单元测试覆盖所有校验场景 |
五、性能优化建议
对于高频API接口,建议:
- 简化Pydantic模型嵌套层级
- 将复杂验证逻辑移到路由处理函数中
- 使用
@validate_arguments装饰器替代完整模型