Working with Middlewares and Events
As Batman's application grew more complex, Robyn taught him about middlewares, startup and shutdown events, and even working with WebSockets. Batman learned how to create functions that could execute before or after a request, manage the application's life cycle, and handle real-time communication with clients using WebSockets.
Handling Events
Batman discovered that he could add startup and shutdown events to manage his application's life cycle. He added the following code to define these events:
Batman was excited to learn that he could add events as functions as well as decorators.
Request
async def startup_handler():
print("Starting up")
app.startup_handler(startup_handler)
@app.shutdown_handler
def shutdown_handler():
print("Shutting down")
For an asynchronous request, Batman used:
Request
from robyn import Request
@app.get("/")
async def h(request: Request) -> str:
return "Hello, world"
Handling Middlewares
Batman learned to use both sync and async functions for middlewares. He wrote the following code to add a middleware that would execute before and after each request. A before request middleware is a function that executes before each request. It can modify the request object or perform any other operation before the request is processed. An after request middleware is a function that executes after each request. It can modify the response object or perform any other operation after the request is processed.
Every before request middleware should accept a request object and return a request object. Every after-request middleware should accept a response object and return a response object on happy case scenario. After-request middlewares can also optionally accept the request object as the first parameter to access request data.
The before_request chain stops as soon as one of its middlewares returns a response object: the remaining before_request middlewares and the route handler (the main entry point) are skipped. The after_request middlewares, however, still run on that response before it is returned to the client — so use them for work that must always happen (e.g. logging, headers), even on a short-circuited 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
Multiple middlewares on the same route
Batman sometimes needed more than one thing to happen before a request — say, logging and input sanitisation — and often alongside authentication. Robyn lets you stack as many before_request and after_request handlers on the same route as you like; they run in the order they were registered.
The before_request chain runs top to bottom and stops early if a handler returns a Response — the remaining before_request middlewares and the route handler are then skipped. The after_request chain always runs over the outgoing response in registration order, whether that response came from the route handler or from an early-returning before_request.
Because auth_required=True is itself a before_request hook, it composes with your own middlewares: authentication runs first, then your custom filters.
Multiple middlewares
from robyn import Request, Response
@app.get("/index", auth_required=True) # 1. auth runs first
async def index(request: Request):
return "Index Page"
@app.before_request("/index") # 2. then this
async def log_request(request: Request):
print("logging:", request.url.path)
return request
@app.before_request("/index") # 3. then this — all run, in order
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
What's next?
Robyn - Great, you're now familiar with the certain advanced concepts of Robyn.
Batman - "Authentication! I want to learn about authentication. I want to make sure that only the right people can access my application."
Robyn - Yes, Authentication!
