2017-04-09 23 views
0

我正在嘗試構建Flask API,並且我有一個端點應該創建一個用戶,另一個端點應該檢查用戶是否存在於數據庫中:使用Flask從API調用端點的正確方法

@API.route('/users/', methods=['POST']) 
def new_user(): 
    user_json = json.loads(request.get_json()) 
    first_name = user_json.get('first_name') 
    last_name = user_json.get('last_name') 
    email = user_json.get('email') 
    password = user_json.get('password') 
    # Call the other endpoint here 
    if response == 400: 
     try: 
      user = User(first_name=first_name, last_name=last_name, email=email, password=password) 
      db.session.add(user) 
      db.session.commit() 
      return jsonify(user=user.to_json()), 200 
     except: 
      return jsonify(error=500), 500 
    else: 
     return jsonify(user=user.to_json()), 409 



@API.route('/users/<string:email>', methods=['GET']) 
def is_present(email): 
    user = User.query.filter_by(email=email).first() 
    if user: 
     print(user) 
     return jsonify(user=user.to_json()), 200 
    else: 
     return jsonify(error=404), 404 

的問題是我不知道什麼是叫我is_presentnew_user終點的最佳途徑。我應該使用requests.get?或者在Flask中是否有特定的其他人這樣做?

回答

2

處理此問題的常用方法是將視圖的邏輯分解爲單獨的內部函數(即不通過API公開),並調用內部函數。然後視圖將處理請求,並根據需要調用內部函數。雖然在此情況下(這只是一個數據庫查詢)微不足道的,這是怎麼可以這樣做:

def get_user(email): 
    return User.query.filter_by(email=email).first() 

@API.route('/users/', methods=['POST']) 
def new_user(): 
    user_json = json.loads(request.get_json()) 
    first_name = user_json.get('first_name') 
    last_name = user_json.get('last_name') 
    email = user_json.get('email') 
    password = user_json.get('password') 
    user = get_user(email) 
    if not user: 
     try: 
      user = User(first_name=first_name, last_name=last_name, email=email, password=password) 
      db.session.add(user) 
      db.session.commit() 
      return jsonify(user=user.to_json()), 200 
     except: 
      return jsonify(error=500), 500 
    else: 
     return jsonify(user=user.to_json()), 409 

@API.route('/users/<string:email>', methods=['GET']) 
def is_present(email): 
    user = get_user(email) 
    if user: 
     print(user) 
     return jsonify(user=user.to_json()), 200 
    else: 
     return jsonify(error=404), 404 

使用這種方法的一個明顯的好處就是HTTP請求是完全可以避免的,帶來了更高效且不易出錯(例如網絡問題)解決方案。


說了上述的一般處理來自多個視圖訪問常用的功能,創建新的用戶不能總是保證用戶創建不會失敗是由於重複的記錄之前執行的查詢方式。有一個競爭條件;在第一次請求檢查之後但在嘗試創建操作之前,可能會有另一個請求創建用戶。

假設你的用戶表有一個主鍵,例如在(first_name, last_name, email)上,您可以簡單地嘗試創建新用戶並處理由於重複而引發的任何異常。或者,你可能想看看Session.merge()

+0

的小費好,謝謝!我想正確地編寫代碼,我應該在哪裏放置函數'get_user'到我的倉庫中?如果我仍然有需要訪問另一個端點的端點,我應該怎麼做? – mel

+0

如果你堅持發出HTTP請求,'requests'是個不錯的選擇。 Flask確實提供了['test_client()'](http://flask.pocoo.org/docs/0.12/api/#flask.Flask.test_client),所以如果你能克服它被命名爲「test 「客戶端,而不是通用的HTTP客戶端。 – mhawke

+1

把'get_user()'放在哪裏?如果你有一個模型文件,它可以去那裏,否則無論'User'類聲明哪裏都是最好的地方。 – mhawke

0

我會爲您的使用情況做這樣的事情:

@API.route('/users', defaults={'email': None} ,methods=['GET', 'POST']) 
@API.route('/users/<string:email>', methods=['GET', 'POST']) 
def new_user(email): 
    if(email): 
     user = User.query.filter_by(email=email).first() 
     if user: 
      return jsonify(user=user.to_json()), 200 
     else: 
      return jsonify(error=404), 404 
    else: 
     user_json = json.loads(request.get_json()) 
     first_name = user_json.get('first_name') 
     last_name = user_json.get('last_name') 
     email = user_json.get('email') 
     password = user_json.get('password') 
     user = User(first_name=first_name, last_name=last_name, email=email, password=password) 
     db.session.add(user) 
     db.session.commit() 
     return jsonify(user=user.to_json()), 200