api/app/core/middleware.py
2025-04-09 11:06:26 +08:00

68 lines
2.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from typing import Any, Callable, Dict, Optional
from fastapi import FastAPI, Request, Response
from fastapi.responses import JSONResponse
import json
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.types import ASGIApp
from app.schemas.response import StandardResponse, ErrorResponse
class ResponseMiddleware(BaseHTTPMiddleware):
"""
中间件统一处理API响应格式
请求正确:{code:200, data:Any}
业务错误:{code:500, message:""}
"""
async def dispatch(self, request: Request, call_next: Callable) -> Response:
# 不需要处理的路径
exclude_paths = ["/docs", "/redoc", "/openapi.json"]
if any(request.url.path.startswith(path) for path in exclude_paths):
return await call_next(request)
response = await call_next(request)
# 如果是HTTPException直接返回不进行封装
if response.status_code >= 400:
return response
# 正常响应进行封装
if response.status_code < 300 and response.headers.get("content-type") == "application/json":
response_body = [chunk async for chunk in response.body_iterator]
response_body = b"".join(response_body)
if response_body:
try:
data = json.loads(response_body)
# 已经是统一格式的响应,不再封装
if isinstance(data, dict) and "code" in data and ("data" in data or "message" in data):
return Response(
content=response_body,
status_code=response.status_code,
headers=dict(response.headers),
media_type=response.media_type
)
# 封装为标准响应格式
result = StandardResponse(code=200, data=data).model_dump()
return JSONResponse(
content=result,
status_code=response.status_code,
headers=dict(response.headers)
)
except json.JSONDecodeError:
# 非JSON响应直接返回
return Response(
content=response_body,
status_code=response.status_code,
headers=dict(response.headers),
media_type=response.media_type
)
return response
def add_response_middleware(app: FastAPI) -> None:
"""添加响应处理中间件到FastAPI应用"""
app.add_middleware(ResponseMiddleware)