【问题标题】:how to terminate rest request gracefully如何优雅地终止休息请求
【发布时间】:2021-05-10 01:08:44
【问题描述】:

如果输入参数丢失,我想终止到达服务器的休息请求而不做进一步处理。

目前这是实现,我认为这对 verify_required_pa​​rams() 不是很好。

如果缺少参数,我想终止此请求而不从 verify_required_pa​​rams() 返回任何值。否则流程应该继续。

在烧瓶服务器上运行它并打开以包含任何新包以获得最佳/优化方法。

请有人为此提出优化方法吗?

@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

【问题讨论】:

    标签: python-3.x flask flask-restful


    【解决方案1】:

    ? You say it works in a RESTful way, then your errors come back as 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)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-04
      • 1970-01-01
      • 2015-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多