fastapi middleware中间件
一、介绍
FastAPI中的中间件(Middleware)是一个非常重要的概念,它允许开发者在请求被处理之前和响应被发送之前执行自定义逻辑。中间件在Web应用程序中扮演着桥梁的角色,连接着客户端的请求和服务器端的响应处理过程。以下是FastAPI中间件概念的详细解释:
1. 中间件的定义
在FastAPI中,中间件是一个函数,它在每个请求被特定的路径操作处理之前,以及在每个响应返回给客户端之前执行。中间件可以执行诸如日志记录、身份验证、请求/响应修改等跨路径操作的通用逻辑。
2. 中间件的作用
- 请求处理前:中间件可以在请求到达处理函数之前执行一些逻辑,如记录请求信息、进行身份验证、修改请求数据等。
- 响应处理前:在处理函数生成响应后,但在响应返回给客户端之前,中间件可以执行一些逻辑,如修改响应头、记录响应信息等。
二、示例
中间件可以通过装饰器@app.middleware("http")
来定义,或者通过app.add_middleware()
方法直接添加到应用程序中
1、官方demo
import time
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
response.headers["X-Process-Time"] = str(process_time)
return response
2、自定义中间件
创建 app/middleware/headers.py。中间件的实现是通过继承BaseHTTPMiddleware
类并定义dispatch
方法来实现的。dispatch
方法是中间件的核心,因为它定义了中间件如何处理进入的请求(Request
)和如何接收或修改响应(Response
)。
import time
from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.responses import Response
class UseTimeMiddleware(BaseHTTPMiddleware):
""" 计算耗时中间件"""
def __init__(self, app):
super().__init__(app)
# 重写BaseHTTPMiddleware类中的dispatch方法
async def dispatch(self, request: Request, call_next) -> Response:
""" 请求耗时 """
start_time = time.time()
# 调用下一个中间件或路由处理函数
response = await call_next(request)
process_time = time.time() - start_time
response.headers["X-Process-Time"] = str(process_time)
return response
app/middleware/__init__.py,封装中间件注册函数
from fastapi import FastAPI
from .headers import UseTimeMiddleware
def registerMiddlewareHandle(app: FastAPI):
# 添加耗时请求中间件
app.add_middleware(UseTimeMiddleware)
初始化fastapi
from app import errors, middleware
...
# 实例化
app = FastAPI()
# # 注册中间件
middleware.registerMiddlewareHandle(app)
三、常用中间件
1、跨域中间件
from fastapi.middleware.cors import CORSMiddleware
# 注册
server.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 允许的来源,可以是字符串、字符串列表,或通配符 "*"
allow_credentials=True, # 是否允许携带凭证(例如,使用 HTTP 认证、Cookie 等)
allow_methods=["*"], # 允许的 HTTP 方法,可以是字符串、字符串列表,或通配符 "*"
allow_headers=["*"], # 允许的 HTTP 头信息,可以是字符串、字符串列表,或通配符 "*"
expose_headers=["*"], # 允许前端访问的额外响应头,可以是字符串、字符串列表
max_age=600, # 请求的缓存时间,以秒为单位
)
2、Gzip压缩中间件
from fastapi.middleware.gzip import GZipMiddleware
# 注册
server.add_middleware(
GZipMiddleware,
minimum_size=500, # 启用 Gzip 压缩的最小响应体大小,单位为字节
compresslevel=6 # Gzip 压缩级别,范围为 0 到 9,级别越高,压缩率越高,但耗费的 CPU 越多
)