Sanic框架中间件(Middleware)深度解析
sanic 项目地址: https://gitcode.com/gh_mirrors/san/sanic
什么是中间件
在Sanic框架中,中间件是一种强大的机制,允许开发者在HTTP请求/响应生命周期的特定阶段插入自定义逻辑。与监听器(Listener)关注工作进程的生命周期不同,中间件专注于HTTP流的处理过程。
中间件的基本类型
Sanic支持两种主要类型的中间件:
- 请求中间件(Request Middleware):在路由处理器执行前运行
- 响应中间件(Response Middleware):在路由处理器执行后运行
@app.on_request
async def pre_handler(request):
print("请求处理前的逻辑")
@app.on_response
async def post_handler(request, response):
print("请求处理后的逻辑")
中间件的工作原理
让我们通过一个序列图来理解中间件的执行流程:
- 请求到达Worker进程
- 按注册顺序执行所有请求中间件
- 执行匹配的路由处理器
- 按注册的相反顺序执行所有响应中间件
- 返回最终响应给客户端
中间件的注册方式
Sanic提供了多种注册中间件的方式,开发者可以根据喜好选择:
方法一:使用装饰器
@app.middleware("request")
async def extract_user(request):
request.ctx.user = await get_user(request)
方法二:使用register_middleware方法
async def auth_middleware(request):
if not request.token:
return text("Unauthorized", status=401)
app.register_middleware(auth_middleware, "request")
方法三:简化装饰器语法
@app.on_request
async def extract_user(request):
...
@app.on_response
async def add_security_headers(request, response):
...
中间件的常见用途
请求预处理
@app.on_request
async def add_request_id(request):
# 为每个请求添加唯一ID
request.ctx.request_id = str(uuid.uuid4())
响应后处理
@app.on_response
async def add_security_headers(request, response):
# 添加安全相关的HTTP头
response.headers["X-Content-Type-Options"] = "nosniff"
response.headers["X-Frame-Options"] = "DENY"
路由参数修改
@app.on_request
def normalize_slug(request: Request):
# 统一slug格式
if "slug" in request.match_info:
request.match_info["slug"] = request.match_info["slug"].lower()
中间件的执行顺序
理解中间件的执行顺序至关重要:
- 请求中间件按注册顺序执行
- 路由处理器执行
- 响应中间件按注册的相反顺序执行
@app.on_request # 1. 第一个执行
async def middleware_1(request):
print("Middleware 1")
@app.on_request # 2. 第二个执行
async def middleware_2(request):
print("Middleware 2")
@app.on_response # 4. 第四个执行 (响应中间件逆序)
async def middleware_3(request, response):
print("Middleware 3")
@app.on_response # 3. 第三个执行
async def middleware_4(request, response):
print("Middleware 4")
高级中间件技巧
提前响应
中间件可以通过返回HTTPResponse对象来中断请求处理流程:
@app.on_request
async def check_auth(request):
if not request.headers.get("Authorization"):
return json({"error": "Unauthorized"}, status=401)
优先级控制
从Sanic v22.9开始,可以通过priority参数控制中间件执行顺序:
@app.on_request(priority=10) # 高优先级,先执行
async def high_priority_middleware(request):
...
@app.on_request(priority=-10) # 低优先级,后执行
async def low_priority_middleware(request):
...
最佳实践建议
- 将中间件逻辑保持简洁单一
- 避免在中间件中进行耗时操作
- 合理使用请求上下文(request.ctx)存储请求级数据
- 考虑中间件性能影响,特别是对于高频路由
- 使用类型注解提高代码可读性
通过合理使用中间件,开发者可以在Sanic应用中实现各种横切关注点,如认证、日志、监控等,保持业务代码的整洁和可维护性。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考