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.
# 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:
mask = '{name, age, pet{name}}'
Nesting specification works with nested object or list of objects:
# 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:
# 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.
class MyResource(Resource):
@api.marshal_with(my_model, mask='name,age')
def get(self):
pass
Default mask can also be handled at model level:
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:
{"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.