Last active
December 14, 2015 18:59
-
-
Save akaariai/5132829 to your computer and use it in GitHub Desktop.
Call-through middleware
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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