使用FastAPI时如何解决"422 Unprocessable Entity"错误?

一、问题现象与本质分析

当使用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": "必须是整数"
        })

三、高级调试技巧

  1. 启用调试模式app = FastAPI(debug=True)
  2. 使用HTTPie测试http POST :8000/items/ name="Foo" price=invalid
  3. 分析错误详情:422响应会包含详细的错误定位信息

四、预防性编程实践

问题类型 预防措施
数据类型错误 使用mypy进行静态类型检查
字段缺失 编写完整的API文档示例
复杂验证 添加单元测试覆盖所有校验场景

五、性能优化建议

对于高频API接口,建议:

  • 简化Pydantic模型嵌套层级
  • 将复杂验证逻辑移到路由处理函数中
  • 使用@validate_arguments装饰器替代完整模型