107 lines
2.6 KiB
ReStructuredText
107 lines
2.6 KiB
ReStructuredText
Fields masks
|
|
============
|
|
|
|
Flask-RESTX support partial object fetching (aka. fields mask)
|
|
by supplying a custom header in the request.
|
|
|
|
By default the header is ``X-Fields``
|
|
but it can be changed with the ``RESTX_MASK_HEADER`` parameter.
|
|
|
|
Syntax
|
|
------
|
|
|
|
The syntax is actually quite simple.
|
|
You just provide a coma separated list of field names,
|
|
optionally wrapped in brackets.
|
|
|
|
.. code-block:: python
|
|
|
|
# These two mask are equivalents
|
|
mask = '{name,age}'
|
|
# or
|
|
mask = 'name,age'
|
|
data = requests.get('/some/url/', headers={'X-Fields': mask})
|
|
assert len(data) == 2
|
|
assert 'name' in data
|
|
assert 'age' in data
|
|
|
|
To specify a nested fields mask,
|
|
simply provide it in bracket following the field name:
|
|
|
|
.. code-block:: python
|
|
|
|
mask = '{name, age, pet{name}}'
|
|
|
|
Nesting specification works with nested object or list of objects:
|
|
|
|
.. code-block:: python
|
|
|
|
# Will apply the mask {name} to each pet
|
|
# in the pets list.
|
|
mask = '{name, age, pets{name}}'
|
|
|
|
There is a special star token meaning "all remaining fields".
|
|
It allows to only specify nested filtering:
|
|
|
|
.. code-block:: python
|
|
|
|
# Will apply the mask {name} to each pet
|
|
# in the pets list and take all other root fields
|
|
# without filtering.
|
|
mask = '{pets{name},*}'
|
|
|
|
# Will not filter anything
|
|
mask = '*'
|
|
|
|
|
|
Usage
|
|
-----
|
|
|
|
By default, each time you use ``api.marshal`` or ``@api.marshal_with``,
|
|
the mask will be automatically applied if the header is present.
|
|
|
|
The header will be exposed as a Swagger parameter each time you use the
|
|
``@api.marshal_with`` decorator.
|
|
|
|
As Swagger does not permit exposing a global header once
|
|
it can make your Swagger specifications a lot more verbose.
|
|
You can disable this behavior by setting ``RESTX_MASK_SWAGGER`` to ``False``.
|
|
|
|
You can also specify a default mask that will be applied if no header mask is found.
|
|
|
|
.. code-block:: python
|
|
|
|
class MyResource(Resource):
|
|
@api.marshal_with(my_model, mask='name,age')
|
|
def get(self):
|
|
pass
|
|
|
|
|
|
Default mask can also be handled at model level:
|
|
|
|
.. code-block:: python
|
|
|
|
model = api.model('Person', {
|
|
'name': fields.String,
|
|
'age': fields.Integer,
|
|
'boolean': fields.Boolean,
|
|
}, mask='{name,age}')
|
|
|
|
|
|
It will be exposed into the model `x-mask` vendor field:
|
|
|
|
.. code-block:: JSON
|
|
|
|
{"definitions": {
|
|
"Test": {
|
|
"properties": {
|
|
"age": {"type": "integer"},
|
|
"boolean": {"type": "boolean"},
|
|
"name": {"type": "string"}
|
|
},
|
|
"x-mask": "{name,age}"
|
|
}
|
|
}}
|
|
|
|
To override default masks, you need to give another mask or pass `*` as mask.
|