Sanic框架中间件(Middleware)深度解析

Sanic框架中间件(Middleware)深度解析

sanic sanic 项目地址: https://gitcode.com/gh_mirrors/san/sanic

什么是中间件

在Sanic框架中,中间件是一种强大的机制,允许开发者在HTTP请求/响应生命周期的特定阶段插入自定义逻辑。与监听器(Listener)关注工作进程的生命周期不同,中间件专注于HTTP流的处理过程。

中间件的基本类型

Sanic支持两种主要类型的中间件:

  1. 请求中间件(Request Middleware):在路由处理器执行前运行
  2. 响应中间件(Response Middleware):在路由处理器执行后运行
@app.on_request
async def pre_handler(request):
    print("请求处理前的逻辑")

@app.on_response
async def post_handler(request, response):
    print("请求处理后的逻辑")

中间件的工作原理

让我们通过一个序列图来理解中间件的执行流程:

  1. 请求到达Worker进程
  2. 按注册顺序执行所有请求中间件
  3. 执行匹配的路由处理器
  4. 按注册的相反顺序执行所有响应中间件
  5. 返回最终响应给客户端

中间件的注册方式

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()

中间件的执行顺序

理解中间件的执行顺序至关重要:

  1. 请求中间件按注册顺序执行
  2. 路由处理器执行
  3. 响应中间件按注册的相反顺序执行
@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):
    ...

最佳实践建议

  1. 将中间件逻辑保持简洁单一
  2. 避免在中间件中进行耗时操作
  3. 合理使用请求上下文(request.ctx)存储请求级数据
  4. 考虑中间件性能影响,特别是对于高频路由
  5. 使用类型注解提高代码可读性

通过合理使用中间件,开发者可以在Sanic应用中实现各种横切关注点,如认证、日志、监控等,保持业务代码的整洁和可维护性。

sanic sanic 项目地址: https://gitcode.com/gh_mirrors/san/sanic

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杜月锴Elise

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值