Middleware with Routes
Often an application needs to modify or monitor what is happening before and after when a route has been called. To this end a middleware layer is helpful. You can define a class with methods to handle what happens.
Methods should be named and prefixed as below
before_
- Triggers before a route has been hitafter_
- Triggers after a route has been hitbefore_and_after_
- Triggers both before and after a route has been hit
Example of a simple "MiddleWare"
In this example we are using the events triggered to modify headers and content. The routes annotated by this middle ware will have their content modified. The example below also implies one can use it for securing CORS and authentication purposes.
src/app/MiddleWare.py
class MiddleWare:
@staticmethod
def before_route(request, response):
response.headers['Tina4-Control-Allow-Origin-Before'] = '*'
response.content = "Before"
return request, response
@staticmethod
def before_something_else(request, response):
response.headers['Tina4-Control-Allow-Origin-Before-Something-Else'] = '*'
response.content = "Before"
return request, response
@staticmethod
def after_route(request, response):
response.headers['Tina4-Control-Allow-Origin-After'] = '*'
response.content += "MEH"
return request, response
@staticmethod
def before_and_after_route(request, response):
response.content += "Before After"
response.headers['Tina4-Control-Allow-Origin-BEFORE_AFTER'] = '*'
return request, response
Annotating the routes
The following examples apply to the middle ware above, we can also be specific about which events should fire otherwise the events will just be fired according to the naming conventions.
# import the middleware annotation
from tina4_python.Router import get, middleware
# import our custom middleware class, it could have been called something else as well
from src.app.MiddleWare import MiddleWare
# Generic middleware set to fire before_route, after_route and before_and_after
@middleware(MiddleWare)
@get("/test/redirect")
async def redirect(request, response):
return response.redirect("/hello/world")
# This middle ware will fire the before_and_after method only
@middleware(MiddleWare, ["before_and_after_route"])
@get("/system/roles/data")
async def system_roles(request, response):
print("roles ggg")
return response("OK")
Hot Tips
- Make sure your middleware annotation is before the route annotation
- Middleware routes always have a
request
andresponse
variable