python-3.x - 如何优雅地终止休息请求
问题描述
如果缺少输入参数,我想终止到达服务器的休息请求而不进行进一步处理。
目前这是实现,我认为这对verify_required_params()不是很好。
如果缺少参数,我想终止此请求而不从verify_required_params()返回任何值。否则流程应该继续。
在烧瓶服务器上运行它并打开以包含任何新包以获得最佳/优化方法。
请有人为此建议一种优化方法吗?
@app.route('/is_registered', methods=['POST'])
def is_registered():
_json = request.get_json()
keys = _json.keys()
customer = Customer()
if verify_required_params(['mobile'], keys) is True:
_mobile = _json['mobile']
validated = validate_mobile(_mobile)
registered = customer.find(_mobile)
if not validated:
response = get_response('MOBILE_NUMBER_NOT_VALID')
return jsonify(response)
if not registered:
response = get_response('MOBILE_NUMBER_NOT_REGISTERED')
return jsonify(response)
response = get_response('MOBILE_NUMBER_REGISTERED')
return jsonify(response)
else:
return verify_required_params(['mobile'], keys)
def verify_required_params(required, received):
required = set(required)
received = set(received)
missing = list(sorted(required - received))
data = {"missing_key(s)": missing}
# response = app.response_class(
# response=json.dumps(data),
# status=200,
# mimetype='application/json'
# )
if missing:
return jsonify(data)
return True
解决方案
您说它以 RESTful 方式工作,然后您的错误返回 200 OK
在 REST 中,您的 URL 应该对有关您的实体的所有信息进行编码。在您的情况下,您通过他们的电话号码识别客户,并且您正在获取而不是更新有关他们的信息,因此您的端点应该看起来像GET /client/<phonenumber>/registered
. 这样一来,请求就无法在不转到不同端点的情况下提供此信息。
简而言之,您的代码将替换为:
@app.route('/client/<mobile>/registered', methods=['GET'])
def is_registered(mobile):
if not mobile.is_decimal():
return jsonify({'error': 'mobile is not number'}), 400 # Bad Request
customer = Customer()
registered = bool(customer.find(mobile))
# does it make sense to have a customer who is not registered yet?
# if not, use:
if not registered:
return jsonify({'error': 'client not found'}), 404 # Not Found
validated = validate_mobile(mobile)
return jsonify( {'validated': validated, 'registered': registered} )
另外,验证函数最好是装饰器。这样它就会在函数的实际业务逻辑之前被调用。对于检查是否request.get_json()
包含正确字段的示例,它的外观如下:
import functools
def requires_fields(fields):
required_fields = set(fields)
def wrapper(func):
@functools.wraps(decorated)
def decorated(*args, **kwargs):
current_fields = set(request.get_json().keys())
missing_fields = required_fields
if missing_fields:
return jsonify({'error': 'missing fields', 'fields': list(missing_fields)}), 400 # Bad Request
resp = func(*args, **kwargs)
return resp
return wrapper
# usage:
@app.route('/comment', methods=['POST'])
@requires_fields(['author', 'post_id', 'body'])
def create_comment():
data = request.get_json()
id = FoobarDB.insert('comment', author=data['author'], post_id=data['post_id'], body=data['body'])
return jsonify({'new_id': id}), 201 # Created
如果你必须保持它现在的样子,那么为了不从验证函数返回数据,你必须提出一个HTTPException
. 执行此操作的默认功能是flask.abort(code)
.
推荐阅读
- laravel - 如何在模型构造函数中注入参数?
- ios - 从 Scrollview 中的 UIimageView 获取可见部分图像
- sap - 为什么集成总线在 CreateObject 事件上执行 3 次,为什么在 Kentico 的传出同步期间站点名称为空?
- wordpress - 如何在 ReactJS 中使用 WP 挂钩
- python - 从 c++ 转换为 python - 如何在 python 中声明一个没有定义的虚拟方法
- javascript - 滚动固定标题未显示在移动设备上
- kubernetes - 使用 Google Cloud 中的抢占式虚拟机对 Kubernetes 进行故障保存
- angular-cli - 运行我的项目期间出现 Angular ng 服务命令错误
- node.js - Nodejs从API调用捕获响应
- c# - 如何提高 datagridview 标题颜色和列隐藏性能?