You can use middleware to affect the evaluation of fields in your schema.

A middleware is any object or function that responds to resolve(next_middleware, *args).

Inside that method, it should either:

  • Send resolve to the next middleware to continue the evaluation; or
  • Return a value to end the evaluation early.

Resolve arguments

Middlewares resolve is invoked with several arguments:

  • next represents the execution chain. Call next to continue evaluation.
  • root is the root value object passed throughout the query.
  • info is the resolver info.
  • args is the dict of arguments passed to the field.


This middleware only continues evaluation if the field_name is not 'user'

class AuthorizationMiddleware(object):
    def resolve(self, next, root, info, **args):
        if info.field_name == 'user':
            return None
        return next(root, info, **args)

And then execute it with:

result = schema.execute('THE QUERY', middleware=[AuthorizationMiddleware()])

If the middleware argument includes multiple middlewares, these middlewares will be executed bottom-up, i.e. from last to first.

Functional example

Middleware can also be defined as a function. Here we define a middleware that logs the time it takes to resolve each field:

from time import time as timer

def timing_middleware(next, root, info, **args):
    start = timer()
    return_value = next(root, info, **args)
    duration = round((timer() - start) * 1000, 2)
    parent_type_name = root._meta.name if root and hasattr(root, '_meta') else ''
    logger.debug(f"{parent_type_name}.{info.field_name}: {duration} ms")
    return return_value

And then execute it with:

result = schema.execute('THE QUERY', middleware=[timing_middleware])