07. 后端封装统一响应格式+全局异常处理
VsCode 插件显示文件夹、文件图标 专属彩色图标
推荐安装插件 Material Icon Theme ,显示文件夹、文件图标 专属彩色图标

封装统一返回格式 Response
common/response.py
from typing import Any
from pydantic import BaseModel
class Response(BaseModel):
"""统一封装的返回格式"""
code: int
message: str
data: Any = None
@classmethod
def success(cls, message: str = "请求成功", data: Any = None):
return cls(code=200, message=message, data=data)
@classmethod
def error(cls, code: int = 500, message: str = "请求失败"):
return cls(code=code, message=message)
成功调用:
return Response.success(
data=user,
message="登录成功",
)返回:
{
"code": 200,
"message": "登录成功",
"data": {
"id": 1,
"username": "admin"
}
}失败调用:
return Response.error(
message="账号或密码错误",
)返回:
{
"code": 500,
"message": "账号或密码错误",
"data": null
}自定义异常+全局异常处理
common/exceptions.py
from fastapi import HTTPException, Request
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
from app.common.response import Response
class BusinessException(Exception):
"""自定义的业务异常"""
def __init__(self, message: str, code: int = 500):
self.message = message
self.code = code
super().__init__(message)
async def bussiness_excpetion_hadler(request: Request, exc: BusinessException):
"""自定义业务异常处理器"""
return JSONResponse(
status_code=200,
content=Response.error(code=exc.code, message=exc.message).model_dump(),
)
async def http_excpetion_hadler(request: Request, exc: HTTPException):
"""Http异常处理器"""
return JSONResponse(
status_code=exc.status_code,
content=Response.error(code=exc.status_code, message=exc.detail).model_dump(),
)
async def validation_excpetion_hadler(request: Request, exc: RequestValidationError):
"""参数异常处理器"""
return JSONResponse(
status_code=422,
content=Response.error(code=422, message="请求参数校验错误").model_dump(),
)
async def global_excpetion_hadler(request: Request, exc: Exception):
"""全局异常处理器"""
return JSONResponse(
status_code=500,
content=Response.error(code=500, message="服务器内部错误").model_dump(),
)
main.py 注册异常处理器
from fastapi import FastAPI, HTTPException
from fastapi.exceptions import RequestValidationError
from app.common.exceptions import (
BusinessException,
bussiness_excpetion_hadler,
http_excpetion_hadler,
validation_excpetion_hadler,
global_excpetion_hadler,
)
# 注册异常处理器
app.add_exception_handler(BusinessException, bussiness_excpetion_hadler)
app.add_exception_handler(HTTPException, http_excpetion_hadler)
app.add_exception_handler(RequestValidationError, validation_excpetion_hadler)
# 全局的异常兜底,必须放在最后注册!!
app.add_exception_handler(Exception, global_excpetion_hadler)修改登录返回的 schema
class LoginResponse(BaseModel):
token: str
user: UserResponse修改登录 api 完整版
from fastapi import APIRouter, Depends
from app.common.exceptions import BusinessException
from app.common.response import Response
from app.schemas.auth import LoginRequest, LoginResponse
from sqlalchemy.orm import Session
from app.database import get_db
from app.models.user import User
from app.schemas.user import UserResponse
from app.utils.password import verify_password
from app.utils.jwt import create_access_token
router = APIRouter(prefix="/auth", tags=["权限验证"])
@router.post("/login")
def login(data: LoginRequest, db: Session = Depends(get_db)):
# 根据用户账号查询数据库
user = db.query(User).filter(User.username == data.username).first()
# 判断账号和密码是否正确
if not user or not verify_password(data.password, user.password):
raise BusinessException(message="账号或密码错误")
# 验证账号的状态
if user.status != 1:
raise BusinessException(message="账号被禁用")
# 创建token
token = create_access_token(user.id)
# 返回信息
return Response.success(
message="登录成功",
data=LoginResponse(token=token, user=UserResponse.model_validate(user)),
)