RESTful 和flask-restful的筆記
阿新 • • 發佈:2018-11-09
前後端分離簡單理解
flask中返回json格式資料
from flask import jsonify # 返回json資料 @app.route('/') def hello_world(): data = { 'msg': 'ok', 'status': '200', } return jsonify(data)
簡單前後端分離:
前端頁面變成一個靜態檔案。存放在專案的static/html目錄下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Score List</title> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> <script> $(function (){ $.getJSON("/getscores/", function (data){ console.log(data); var scores = data["scores"]; var $ul = $("#score_container"); for(var i=0; i < scores.length; i++){ var $li = $("<li></li>").html(scores[i]); $ul.append($li); } }) }) </script> </head> <body> <h2>機試成績表</h2> <ul id="score_container"></ul> </body> </html>
後端只需要返回json資料即可:
@app.route('/getscores/') def get_scores(): data = { 'msg': 'ok', 'status': '200', 'scores': [1,2,3,4,5,6,30,40] } return jsonify(data)
什麼是RESTFul?
-
簡介
REST即表述性狀態傳遞(英文:Representational State Transfer,簡稱REST)是Roy Fielding博士在2000年他的博士論文中提出來的一種軟體架構風格。它是一種針對網路應用的設計和開發方式,可以降低開發的複雜性,提高系統的可伸縮性。 一種軟體架構風格、設計風格,而不是標準,只是提供了一組設計原則和約束條件。它主要用於客戶端和伺服器互動類的軟體。基於這個風格設計的軟體可以更簡潔,更有層次,更易於實現快取等機制。 REST 指的是一組架構約束條件和原則。滿足這些約束條件和原則的應用程式或設計就是 RESTful。遵循restful開發的應用程式介面(API)稱為RESTFul API。 RESTFul的介面都是圍繞資源以及對資源的各種動作展開的。
-
資源
所謂的資源就是在網路中存在的任意實體,哪怕是一條簡單資訊。
-
動作
所謂動作就是資料的CURD。在開發者設計良好的前提下,對網路資源的動作都可抽象為對資源的CURD操作。RESTFul對網路的操作抽象為HTTP的GET、POST、PUT、DELETE等請求的方式以完成對資源的增刪改查。具體對照如下:
方法 行為 示例 GET 獲取資源資訊 http://127.0.0.1:5000/source GET 獲取指定資源 http://127.0.0.1:5000/source/250 POST 建立新的資源 http://127.0.0.1:5000/source PUT 更新指定資源 http://127.0.0.1:5000/source/250 DELETE 刪除指定資源 http://127.0.0.1:5000/source/250 -
資料
通常傳輸的資料格式都採用JSON,有時也可以通過URL的引數進行傳遞
-
工具
說明:postman是一款非常好用的API開發測試工具,可以模擬各種請求 提醒:安裝包,一路next完成安裝,演示一個地址的訪問
參考阮一峰大神的部落格:http://www.ruanyifeng.com/blog/2011/09/restful.html
理解之後再來看RESTful api開發遵循的原則:http://www.ruanyifeng.com/blog/2014/05/restful_api.html
假如獲取電影資源,遵循RESTful api開發原則的程式碼應該怎麼寫:
@app.route('/movie/', methods=["GET", "POST", "PUT", "DELETE"]) def movie(): if request.method == "GET": # 獲取資源 data = { "m_name": "捉妖記" } return jsonify(data) elif request.method == "POST": data = { "msg": "儲存成功" } return jsonify(data) elif request.method == "PUT": data = { "msg": "更新成功" } return jsonify(data) elif request.method == "DELETE": data = { "msg": "刪除成功" } return jsonify(data) else: abort(405)
原生實現RESTful
定義一個user模型
class User(db.Model): id = db.Column(db.Integer, primary_key=True, autoincrement=True) u_name = db.Column(db.String(16), unique=True) u_password = db.Column(db.String(32)) def to_dict(self): return {"u_name": self.u_name, 'u_password': self.u_password}
實現原生RESTful:
@blue.route("/users/<int:id>/", methods=["GET", "POST", "PUT", "DELETE", "PATCH"]) def users(id): if request.method == "GET": page = int(request.args.get("page", default=1)) per_page = int(request.args.get("per_page", default=3)) users = User.query.paginate(page=page, per_page=per_page, error_out=False).items users_dict = [] for user in users: users_dict.append(user.to_dict()) data = { "message": "ok", "status": "200", "data": users_dict } return jsonify(data) elif request.method == "POST": # 更新或建立 username = request.form.get("username") password = request.form.get("password") data = { "message": "ok", "status": "422" } if not username or not password: data["message"] = "引數不正確" return jsonify(data), 422 user = User() user.u_name = username user.u_password = generate_password(password=password) try: db.session.add(user) db.session.commit() data["status"] = "201" except Exception as e: data["status"] = "901" data["message"] = str(e) return jsonify(data), 422 return jsonify(data), 201 elif request.method == "PUT": username = request.form.get("username") password = request.form.get("password") user = User.query.get(id) user.u_name = username user.u_password = generate_password(password) db.session.add(user) db.session.commit() data = { "message": "update success", } return jsonify(data), 201 elif request.method == "DELETE": user = User.query.get(id) data = { "message": "delete success" } if user: db.session.delete(user) db.session.commit() return jsonify(data), 204 else: data["message"] = "指定資料不存在" return jsonify(data) elif request.method == "PATCH": password = request.form.get("password") user = User.query.get(id) user.u_password = generate_password(password) data = { "messgage": "update success" } db.session.add(user) db.session.commit() return jsonify(data), 201 else: abort(405) def generate_password(password): hash = hashlib.md5() hash.update(password.encode("utf-8")) return hash.hexdigest()
前端只需要根據ajax的方法型別來控制對資源的操作:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>UserLogin</title> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> <script type="text/javascript"> $(function () { $("button").click(function () { var username = $("#username").val(); var password = $("#password").val(); $.ajax("/users/5/", { datatype: "json", type: "PATCH", data: "username=" + username + "&password=" + password, success: function (data) { console.log(data); } }) }) } ) </script> </head> <body> <span>使用者名稱:</span><input id="username" type="text" placeholder="請輸入使用者名稱"> <br> <span>密碼:</span> <input id="password" type="password" placeholder="請輸入密碼"> <br> <button>註冊</button> </body> </html>
使用Flask-restful
flask-restuflu中每種資源抽象成類,需要繼承自Resource,來看一個最簡單的例子,把我們的helloword轉化為一個資源:
class Hello(Resource): def get(self): return {"msg": "ok"} def post(self): return {"msg": "create success"}