Flask_restplus recursive json_mapping

1.1k views Asked by At

Is it possible to provide recursive mapping for objects using same json_mapping?

exapmle:

person_json_mapping = api.model('Person', {
    'name': fields.String(),
    'date_of_birth': fields.Date(),
    'parents': fields.List(fields.Nested(##person_json_mapping##))
    }

how to use person_json_mapping inside self?

1

There are 1 answers

0
bgw On BEST ANSWER

There is a way of defining recursive mapping with flask_restplus, with limitation that you must make an assumption on maximum recursion level your situation requires. You wouldn't want to reach Adam and Eva, would you?

Instead of using api.model directly, write a method that builds that model recursively, decrementing an iteration_number argument in each recursive call.

def recursive_person_mapping(iteration_number=10):
    person_json_mapping = {
        'name': fields.String(),
        'date_of_birth': fields.Date()
    }
    if iteration_number:
        person_json_mapping['parents'] = fields.List(fields.Nested(recursive_person_mapping(iteration_number-1)))
    return api.model('Person'+str(iteration_number), person_json_mapping)

then remember to make a function call, when decorating your method with a marshaller, like this:

@api.marshal_with(recursive_person_mapping())
def get(self):
...

Note the round brackets!

It is also worth to note that 'Person'+str(iteration_number) is mandatory if you use swagger. Without adding an iteration_number you will end up with recursion limit overflow, resulting in internal server error. Outside of swagger, mapper will do fine without it though.

After making an arbitrary assumption of maximum level of recursion, it may also be a good idea to automatically notify admin of a situation when recursion limit was exceeded. That might be a responsibility of a method that prepares data, not the marshaller itself.