使用中间件和事件
随着蝙蝠侠的应用程序逐渐变得更加复杂,Robyn 向他介绍了中间件、启动和关闭事件,甚至 WebSocket 的使用。蝙蝠侠学会了如何创建中间件(在请求之前或之后执行的函数),如何管理应用程序的生命周期,并通过 WebSocket 实现与客户端的实时通信。
处理事件
蝙蝠侠发现,通过添加启动和关闭事件,他能够有效地管理应用程序的生命周期。为此,他编写了以下代码来定义这些事件:
此外,蝙蝠侠也了解到,事件不仅可以通过函数来定义,还可以使用装饰器的方式来实现。
对于同步请求,蝙蝠侠使用如下代码:
Request
async def startup_handler():
print("Starting up")
app.startup_handler(startup_handler)
@app.shutdown_handler
def shutdown_handler():
print("Shutting down")
对于异步请求,蝙蝠侠则使用如下代码:
Request
from robyn import Request
@app.get("/")
async def h(request: Request) -> str:
return "Hello, world"
处理中间件
蝙蝠侠学会了如何在中间件中同时使用同步和异步函数。他编写了以下代码,为每个请求添加了在请求之前和之后执行的中间件。 中间件可以分为两类:请求前中间件和请求后中间件。 该函数在每个请求处理之前执行,可以修改请求对象或执行其他操作。 请求后中间件:该函数在每个请求处理之后执行,可以修改响应对象或执行其他操作。
每个请求前中间件都应接收并返回一个请求对象;每个请求后中间件都应接收并返回一个响应对象。请求后中间件也可以选择性地接收请求对象作为第一个参数,以便访问请求数据。
before_request 链会在其中某个中间件返回响应对象时立即停止:后续的 before_request 中间件以及路由处理函数(主入口)都会被跳过。但 after_request 中间件仍会对该响应执行,然后再返回给客户端——因此可以用它们来处理那些必须始终发生的工作(例如日志、响应头),即使请求被提前中止。
Request
from robyn import Request, Response
@app.before_request("/")
async def hello_before_request(request: Request):
request.headers.set("before", "sync_before_request")
return request
@app.after_request("/")
def hello_after_request(response: Response):
response.headers.set("after", "sync_after_request")
return response
同一路由上的多个中间件
蝙蝠侠有时需要在请求之前执行不止一件事——比如同时进行日志记录和输入清洗,并且常常还要配合身份认证。Robyn 允许你在同一个路由上叠加任意多个 before_request 和 after_request 处理函数;它们会按照注册的顺序依次执行。
before_request 链自上而下执行,如果某个处理函数返回了 Response,则提前中止——此时后续的 before_request 中间件和路由处理函数都会被跳过。而 after_request 链始终会按注册顺序对最终返回的响应执行,无论该响应来自路由处理函数还是来自提前返回的 before_request。
由于 auth_required=True 本身就是一个 before_request 钩子,它可以和你自己的中间件组合使用:身份认证先执行,然后才是你的自定义过滤器。
多个中间件
from robyn import Request, Response
@app.get("/index", auth_required=True) # 1. 先执行身份认证
async def index(request: Request):
return "Index Page"
@app.before_request("/index") # 2. 然后执行这个
async def log_request(request: Request):
print("logging:", request.url.path)
return request
@app.before_request("/index") # 3. 再执行这个——全部按顺序运行
async def sanitize(request: Request):
return request
@app.after_request("/index")
async def add_header(response: Response):
response.headers.set("x-processed", "true")
return response
下一步
Robyn - 太好了,中间件是 Robyn 框架的重要组件之一,您现在已经掌握了 Robyn 的一些高级概念。
蝙蝠侠 - 身份验证!我想了解身份验证,确保只有经过身份验证的的人才能访问我的应用程序。
Robyn - 好的,接下来我将为您介绍身份验证!
