在后端程序的接口函数开发中,验证参数是一件非常重要的事情,确保参数是正确的类型以及包含在我们希望的范围之内。如果参数在范围之外,或者不符合的类型,我们都应该给出异常或错误提示信息。参数的验证处理有多种方式,最为简单的方式就是使用条件语句对参数进行判断。这个方法简单易懂,但比较臃肿和繁琐,如果对多个参数、多个条件进行处理,那么代码量就会非常庞大。因此我选择了 python语言中的 marshmallow(棉花糖)来进行验参。最开始是受这篇文章的启发。http://www.cameronmacleod.com/blog/better-validation-flask-marshmallow
我们以单个参数的接口为例。场景为一个简单的排行榜接口,传入一个数字值 rank表示你希望获取该值之前的排行榜。比如rank=50时,则返回前50名的排名及其act_id(用户名) 和score(分数)。我希望传入的rank值是int类型,如果是则执行数据库查询语句,返回一个列表来显示排行榜信息。如果不是则返回错误信息。
1、常规方式的参数验证(if-else语句嵌套)
def show_rank_board():
rank = request.form["rank"]
print(type(rank))
if type(rank) ==int:
board_list = re.zrange("sorted_item", 0, rank, desc=True, withscores=True, score_cast_func=int)
new_list =list(enumerate(board_list, start=1))
result = {"stat":"200", "data": new_list, "msg":"成功显示排行榜数据"}
return json.dumps(result)
else:
return jsonify({"stat":"304", "msg": '数据类型错误'})
可以看到,在一个参数条件下,该if—else语句还是比较简单。但是如果参数变为多个,或者更进一步地来说,我们希望给参数划定一个范围等等。那么这么条件循环语句将会变得非常复杂,且可维护性差。因此,一般不建议使用此方法。
2.marshmallow库
marshamallow是一个开源的库,用于对象序列化。除了解析和转储,它还内置了一些强大的验证功能。
marshamallow的核心思想是用模式表示数据结构。模式是一个类,用于定义数据输入的格式。它指示存在哪些字段,它们的类型以及对它们的验证。您可以通过子类化marshmallow.Schema和创建将代表数据字段的属性来创建架构。
以这个排行榜服务为例,目前需要三个参数。创建CreateNoteInputSchema类
act_id: 用户id,用来唯一标识用户身份的信息,最长为12位。 str类型
new_score: 用户提交的新分数,用来更新榜单 范围在0—10000之间。 int类型
rank: 用户希望查看的前rank名的排行榜,范围在1——1000之间。int类型
我们需要在文件头部导入
from marshmallow.validateimport Length, Range, Regexp
from profile_decoratorimport do_cProfile
Str和Int表示这三个参数必须满足的类型、
required=True,表示必须为正确的表达方式、
validate则是对参数的一系列约束。
完成以上类的建立后,我们需要在函数接口处实例化该类。(ps:only=[]为列表对象,表示在类中选择指定的参数来进入实例化对象进行判断)
create_note_schema = CreateNoteInputSchema(only=["act_id", "new_score"])
我们定义一个errors变量,调用creat_note_schema中的validate函数,传入参数是request.form,即flask框架中传入的参数,这个函数将验证从request表单获取的参数对象,并生成一个字典,储存报错信息,如果传入参数满足在之前 CreateNoteInputSchema类中的定义要求,则为空,否则就会传输出对应的报错信息。例如我输入rank为‘a’,则返回errors:{'rank': ['Not a valid integer.']},非int类型。
errors = create_note_schema.validate(request.form)
据此,我们就可以通过errors进行判断,如果errors为空,则证明所有的参数已经通过验证,就可以继续执行接口函数语句。如果errors存在,也可以很快的了解到是哪个参数,不满足具体哪个条件。
这个方法针对多参数,多判定条件非常有用。极大的提高了验参效率,增强了代码的健壮性。