Using the flask-restful micro-framework, I am having trouble constructing a RequestParser
that will validate nested resources. Assuming an expected JSON resource format of the form:
{
'a_list': [
{
'obj1': 1,
'obj2': 2,
'obj3': 3
},
{
'obj1': 1,
'obj2': 2,
'obj3': 3
}
]
}
Each item in a_list
corresponds to an object:
class MyObject(object):
def __init__(self, obj1, obj2, obj3)
self.obj1 = obj1
self.obj2 = obj2
self.obj3 = obj3
... and one would then create a RequestParser using a form something like:
from flask.ext.restful import reqparse
parser = reqparse.RequestParser()
parser.add_argument('a_list', type=MyObject, action='append')
... but how would you validate the nested MyObject
s of each dictionary inside a_list
? Or, alternately, is this the wrong approach?
The API this corresponds to treats each MyObject
as, essentially, an object literal, and there may be one or more of them passed to the service; therefore, flattening the resource format will not work for this circumstance.
I have had success by creating RequestParser
instances for the nested objects. Parse the root object first as you normally would, then use the results to feed into the parsers for the nested objects.
The trick is the location
argument of the add_argument
method and the req
argument of the parse_args
method. They let you manipulate what the RequestParser
looks at.
Here's an example:
root_parser = reqparse.RequestParser()
root_parser.add_argument('id', type=int)
root_parser.add_argument('name', type=str)
root_parser.add_argument('nested_one', type=dict)
root_parser.add_argument('nested_two', type=dict)
root_args = root_parser.parse_args()
nested_one_parser = reqparse.RequestParser()
nested_one_parser.add_argument('id', type=int, location=('nested_one',))
nested_one_args = nested_one_parser.parse_args(req=root_args)
nested_two_parser = reqparse.RequestParser()
nested_two_parser.add_argument('id', type=int, location=('nested_two',))
nested_two_args = nested_two_parser.parse_args(req=root_args)