如何在FastAPI中返回带指定HTTP响应码的Pydantic对象?
FastAPI中根据服务健康状态返回不同响应码的实现方法
针对你的需求——健康检查接口在服务状态正常时返回200和ServiceHealth对象,异常时返回非200状态码,FastAPI有几种简洁的实现方式:
方法1:使用HTTPException抛出异常
FastAPI的HTTPException可以快速触发指定状态码的响应,同时携带自定义响应内容:
from fastapi import APIRouter, HTTPException, status from pydantic import BaseModel router = APIRouter() class ServiceHealth(BaseModel): http_ok: bool = True database_ok: bool = False def is_everything_ok(self) -> bool: return self.http_ok and self.database_ok @router.get("/health") def health(): health_status = ServiceHealth() # 检查服务状态是否健康 if not health_status.is_everything_ok(): # 抛出503服务不可用异常,同时返回健康状态详情 raise HTTPException( status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail=health_status.dict() ) # 状态正常时返回200和健康对象 return health_status
方法2:直接返回JSONResponse控制状态码
如果不需要触发全局异常处理逻辑,可以直接返回JSONResponse,手动指定状态码和响应体:
from fastapi import APIRouter, status, JSONResponse from pydantic import BaseModel router = APIRouter() class ServiceHealth(BaseModel): http_ok: bool = True database_ok: bool = False def is_everything_ok(self) -> bool: return self.http_ok and self.database_ok @router.get("/health") def health(): health_status = ServiceHealth() if not health_status.is_everything_ok(): return JSONResponse( content=health_status.dict(), status_code=status.HTTP_503_SERVICE_UNAVAILABLE ) return health_status
优化API文档可读性
可以给接口添加多状态码的响应模型说明,让自动生成的OpenAPI文档更清晰:
@router.get( "/health", responses={ 200: {"model": ServiceHealth, "description": "服务状态正常"}, 503: {"model": ServiceHealth, "description": "服务状态不健康(HTTP或数据库异常)"} } ) def health(): health_status = ServiceHealth() if not health_status.is_everything_ok(): return JSONResponse( content=health_status.dict(), status_code=status.HTTP_503_SERVICE_UNAVAILABLE ) return health_status
说明
- 推荐使用
status模块中的常量(如HTTP_503_SERVICE_UNAVAILABLE)代替硬编码数字,代码更易读且不易出错。 - 两种方法都能实现需求,选择哪种取决于是否需要触发全局异常处理器(比如统一日志、错误格式处理)。
内容的提问来源于stack exchange,提问作者poiuytrez
相关产品推荐
相关产品推荐

