解析以及验证请求
当我在以前的文章中实现此服务器的时候,我自己对请求的数据进行验证。例如,在之前版本中如何处理 PUT 的:
- @app.route('/todo/api/v1.0/tasks/<int:task_id>', methods = ['PUT'])
@auth.login_required
def update_task(task_id):
task = filter(lambda t: t['id'] == task_id, tasks)
if len(task) == 0:
abort(404)
if not request.json:
abort(400)
if 'title' in request.json and type(request.json['title']) != unicode:
abort(400)
if 'description' in request.json and type(request.json['description']) is not unicode:
abort(400)
if 'done' in request.json and type(request.json['done']) is not bool:
abort(400)
task[0]['title'] = request.json.get('title', task[0]['title'])
task[0]['description'] = request.json.get('description', task[0]['description'])
task[0]['done'] = request.json.get('done', task[0]['done'])
return jsonify( { 'task': make_public_task(task[0]) } )
在这里, 我必须确保请求中给出的数据在使用之前是有效,这样使得函数变得又臭又长。
Flask-RESTful 提供了一个更好的方式来处理数据验证,它叫做 RequestParser 类。这个类工作方式类似命令行解析工具 argparse。
首先,对于每一个资源需要定义参数以及怎样验证它们:
- from flask.ext.restful import reqparse
- class TaskListAPI(Resource):
- def __init__(self):
- self.reqparse = reqparse.RequestParser()
- self.reqparse.add_argument('title', type = str, required = True,
- help = 'No task title provided', location = 'json')
- self.reqparse.add_argument('description', type = str, default = "", location = 'json')
- super(TaskListAPI, self).__init__()
- # ...
- class TaskAPI(Resource):
- def __init__(self):
- self.reqparse = reqparse.RequestParser()
- self.reqparse.add_argument('title', type = str, location = 'json')
- self.reqparse.add_argument('description', type = str, location = 'json')
- self.reqparse.add_argument('done', type = bool, location = 'json')
- super(TaskAPI, self).__init__()
- # ...
在 TaskListAPI 资源中,POST 方法是唯一接收参数的。参数“标题”是必须的,因此我定义一个缺少“标题”的错误信息。当客户端缺少这个参数的时候,Flask-RESTful 将会把这个错误信息作为响应发送给客户端。“描述”字段是可选的,当缺少这个字段的时候,默认的空字符串将会被使用。一个有趣的方面就是 RequestParser 类默认情况下在 request.values 中查找参数,因此 location 可选参数必须被设置以表明请求过来的参数是 request.json 格式的。
TaskAPI 资源的参数处理是同样的方式,但是有少许不同。PUT 方法需要解析参数,并且这个方法的所有参数都是可选的。
当请求解析器被初始化,解析和验证一个请求是很容易的。 例如,请注意 TaskAPI.put() 方法变的多么地简单:
- def put(self, id):
- task = filter(lambda t: t['id'] == id, tasks)
- if len(task) == 0:
- abort(404)
- task = task[0]
- args = self.reqparse.parse_args()
- for k, v in args.iteritems():
- if v != None:
- task[k] = v
- return jsonify( { 'task': make_public_task(task) } )
使用 Flask-RESTful 来处理验证的另一个好处就是没有必要单独地处理类似 HTTP 400 错误,Flask-RESTful 会来处理这些。
当前内容版权归 pythondoc.com 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 pythondoc.com .