2016-10-31 07:32:00 +03:00
|
|
|
Middleware
|
|
|
|
==========
|
|
|
|
|
|
|
|
You can use ``middleware`` to affect the evaluation of fields in your schema.
|
|
|
|
|
2017-12-08 17:58:03 +03:00
|
|
|
A middleware is any object or function that responds to ``resolve(next_middleware, *args)``.
|
2016-10-31 07:32:00 +03:00
|
|
|
|
|
|
|
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 evalution.
|
|
|
|
- ``root`` is the root value object passed throughout the query.
|
|
|
|
- ``info`` is the resolver info.
|
2017-11-25 15:51:53 +03:00
|
|
|
- ``args`` is the dict of arguments passed to the field.
|
2016-10-31 07:32:00 +03:00
|
|
|
|
|
|
|
Example
|
|
|
|
-------
|
|
|
|
|
|
|
|
This middleware only continues evaluation if the ``field_name`` is not ``'user'``
|
|
|
|
|
|
|
|
.. code:: python
|
|
|
|
|
2017-04-20 10:34:05 +03:00
|
|
|
class AuthorizationMiddleware(object):
|
2017-07-27 13:00:21 +03:00
|
|
|
def resolve(self, next, root, info, **args):
|
2017-04-20 10:34:05 +03:00
|
|
|
if info.field_name == 'user':
|
|
|
|
return None
|
2017-07-27 13:00:21 +03:00
|
|
|
return next(root, info, **args)
|
2016-10-31 07:32:00 +03:00
|
|
|
|
|
|
|
|
|
|
|
And then execute it with:
|
|
|
|
|
|
|
|
.. code:: python
|
|
|
|
|
2017-04-20 10:34:05 +03:00
|
|
|
result = schema.execute('THE QUERY', middleware=[AuthorizationMiddleware()])
|
2017-12-08 17:58:03 +03:00
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
.. code:: python
|
|
|
|
|
|
|
|
from time import time as timer
|
|
|
|
|
|
|
|
def timing_middleware(next, root, info, **args):
|
|
|
|
start = timer()
|
|
|
|
return_value = next(root, info, **args)
|
|
|
|
duration = timer() - start
|
2017-12-08 18:03:20 +03:00
|
|
|
logger.debug("{parent_type}.{field_name}: {duration} ms".format(
|
2018-01-25 00:48:14 +03:00
|
|
|
parent_type=root._meta.name if root and hasattr(root, '_meta') else '',
|
2017-12-08 17:58:03 +03:00
|
|
|
field_name=info.field_name,
|
2017-12-08 18:03:20 +03:00
|
|
|
duration=round(duration * 1000, 2)
|
2017-12-08 17:58:03 +03:00
|
|
|
))
|
|
|
|
return return_value
|
|
|
|
|
|
|
|
|
|
|
|
And then execute it with:
|
|
|
|
|
|
|
|
.. code:: python
|
|
|
|
|
|
|
|
result = schema.execute('THE QUERY', middleware=[timing_middleware])
|