Skip to content

Instantly share code, notes, and snippets.

@akaariai
Last active December 14, 2015 18:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akaariai/5132829 to your computer and use it in GitHub Desktop.
Save akaariai/5132829 to your computer and use it in GitHub Desktop.
Call-through middleware
A quick suggestion - turn middleware process_request, process_response
and process_exception into single method, process. For example tx
middleware would be then written as:
class TXMiddlware(object):
def process(self, request):
with transaction.atomic():
return request.process()
The request.process() will call next middleware with process() in the mw
stack. After all process() have been called, then it will call
process_view() for each middleware. Then call the actual view and finally
bubble up with process_template_response if those are defined.
A middlware needing to do some work on the response would be:
class SomeMiddleware(object):
def process(self, request):
resp = request.process()
resp.some_header = 'someval'
return resp
If the middleware decides to skip the request processing (caching
for example), then this should work:
class CacheMiddleware(object):
def process(self, request):
key = self.get_cache_key(request)
if key in cache:
return cache[key]
else:
resp = request.process()
cache[key] = resp
return resp
Old-style middleware could be wrapped in a backwards
compat class:
class BackwardsCompat(object):
def __init__(self, wrapped):
self.wrapped = wrapped
def process(self, request):
# Checking if the methods are actually present in wrapped is skipped intentionally...
try:
resp = self.wrapped.process_request(request)
if not resp:
resp = request.process()
except Exception as e:
resp = self.wrapped.process_exception(request, e)
finally:
return self.wrapped.process_response(request, response)
Unfortunately the backwards compat middleware isn't fully backwards
compatible as-is. The exact interaction of process_view and
process_template_response isn't as it is currently.
If the backwards compatibility middleware can be made fully backwards
compatible is the big question. Otherwise I think this style of
writing a middleware would make more sense than the current way, where
there is no guarantee that if process_request is called, then
process_response and/or process_exception will be called. As a result
writing TXMiddlware correctly is impossible, just as an example.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment