FastAPI中如何自行校验请求体,缺失必填字段时返回400错误
方案1:全局拦截校验错误,统一返回400
该方案适合所有接口都需要将字段缺失、类型不匹配等请求校验错误返回400的场景,只需添加全局异常处理器即可,无需修改原有接口逻辑:
from fastapi import FastAPI, Request from fastapi.exceptions import RequestValidationError from fastapi.responses import JSONResponse app = FastAPI() # 自定义请求校验错误处理器 @app.exception_handler(RequestValidationError) async def handle_validation_error(request: Request, exc: RequestValidationError): error_details = [] for err in exc.errors(): # 定位错误字段 field_path = ".".join([str(loc) for loc in err["loc"]]) if err["type"] == "value_error.missing": error_details.append(f"必填字段[{field_path}]缺失") else: error_details.append(f"字段[{field_path}]错误:{err['msg']}") return JSONResponse( status_code=400, content={"detail": "; ".join(error_details)} )
添加该处理器后,所有Pydantic校验触发的错误都会自动返回400状态码,你原有接口的代码不需要做任何修改。
方案2:单个接口手动校验,不影响全局
如果只需要当前/student接口返回400,其他接口保持默认的422错误,可修改接口逻辑手动解析校验请求体:
from typing import Optional from fastapi import Body, HTTPException from pydantic import ValidationError @app.post("/student", dependencies=[Depends(check_request_header)], response_model=schemas.Student, status_code=200) def create_student( raw_body: Optional[dict] = Body(None), db: Session = Depends(get_db) ): # 先校验请求体是否为空 if not raw_body: raise HTTPException(status_code=400, detail="请求体不能为空") # 手动触发Pydantic校验,捕获错误转400 try: student = schemas.StudentCreate(**raw_body) except ValidationError as e: err_list = [] for err in e.errors(): field = ".".join([str(loc) for loc in err["loc"]]) err_list.append(f"字段[{field}]错误:{err['msg']}") raise HTTPException(status_code=400, detail="; ".join(err_list)) # 原有业务逻辑不变 db_student = crud.get_student(db, student=student) if db_student: raise HTTPException(status_code=400, detail="该学生信息已存在") return crud.create_student(db=db, student=student)
该方案的优势是灵活性高,可针对单个接口自定义校验规则和错误信息,不会干扰其他接口的默认行为。
内容的提问来源于stack exchange,提问作者Daniel Qiao
相关产品推荐
相关产品推荐

