-
Restful API規范
-
restful api是用於再前端與后台進行通信的一套規范。使用這個規范可以讓前后端開發變得更加輕松
-
協議: 采用http或者https協議
-
數據傳輸格式:
-
數據之間傳輸的格式應該都使用json,而不使用xml
-
-
url鏈接:
-
url鏈接中,不能有動詞,只能有名詞。並且對於一些名詞,如果出現復數,那么應該再后面加s
-
-
-
HTTP請求的方法
-
1.GET: 從服務器上獲取資源
-
2.POST: 在服務器上新創建一個資源
-
3.PUT: 在服務器上更新資源。(客戶端提供所有改變后的數據)
-
4.PATCH: 在服務器上更新資源。(客戶端只提供需要改變的屬性)
-
5.DELETE: 從服務器上刪除資源
-
示例如下
-
GET /user/: 獲取所有用戶
-
POST /user/: 新建一個用戶
-
GET /user/id: 根據id獲取一個用戶
-
PUT /user/id: 更新某個id的用戶的信息(需要提供用戶的所有信息)
-
PATCH /user/id/: 更新某個id的用戶信息(只需用提供需要改變的信息)
-
DELETE /user/id/:刪除一個用戶
-
-
-
狀態碼:
-
狀態碼 原生描述 描述 200 OK 服務器成功響應客戶端的請求 400 INVALID REQUEST 用戶發出的請求有錯誤,服務器沒有進行新建或修改數據的操作 401 Unauthorized 用戶沒有權限訪問這個請求 403 Forbidden 因為某些原因禁止訪問這個請求 404 NOT FOUND 用戶發送的請求的url不存在 406 NOT Acceptable 用戶請求不被服務器接受(比如服務器期望客戶端發送某個字段,但是沒有發送) 500 Internal server error 服務器內部錯誤,比如出現了bug
-
-
-
Flask-Restful插件的基本使用
-
1.安裝: pip3.7 install flask--restful即可安裝
-
2.定義Restful的視圖:
-
如果使用Flask-Restful,那么定義視圖函數的時候,就要繼承自 flask_restful.Resource類,然后再根據當前請求的method來定義相應的方法。比如期望客戶端是使用get方法發送過來的請求,那么就定義一個get方法。類似於MethodView.示例代碼如下
-
from flask import Flask, render_template, url_for from flask_restful import Api,Resource app = Flask(__ name___) #用Api來綁定app api = Api(app) class IndexView(Resource) def get(self,username): return {"username":"xiaoxin"} api.add_resource(IndexView,'/','/login/<username>', endpoint = 'index')
-
-
注意事項
-
1.endpoint是用來給url_for 反轉url的時候指定的。如果不寫endpoint,那么將會使用視圖的名字的小寫來作為endpoint.
-
2.add_resource的第二個參數是訪問這個視圖函數的url,這個url可以跟之前的route一樣,可以傳遞參數。並且還有一點不同的是,這個方法可以傳遞多個url來指定這個視圖函數
-
3.如果你想返回json數據,那么就使用flask_restful,如果你是想渲染模板,那么還是采用之前的方式,就是'app.route'的方式
-
-
-
3.參數解析:
-
Flask-Restful插件提供了類似WTForms來驗證提交的數據是否合法的包,叫做reqparse.以下是基本用法:
-
parser = reqparse.RequestParser() parser.add_argument("username",type = str,help="請輸入用戶名",required= True) args = parser.parse_args()
-
-
add_argument可以指定這個字段的名字,這個字段的數據類型等。以下將對這個方法的一些參數做詳細講解
-
1.default: 默認值,如果這個參數沒有值,那么將使用這個參數指定的值
-
2.required:是否必須。默認為False,如果設置為True,那么這個參數就必須提交上來
-
3.type:這個參數的數據類型,如果指定,那么將使用指定的數據類型來強制轉換提交上來的值
-
4.choices: 選項。提交上來的值只有滿足這個選項中的值才符號驗證通過,否則驗證不通過,傳的是一個列表
-
5.help:錯誤信息。如果驗證失敗后,將會使用這個參數指定的值作為錯誤信息
-
6.trim: 是否要去掉前后的空格
-
-
其中的type,可以使用python自帶的一些數據類型,也可以使用flask_restful.inputs下的一些特定的數據類型來強制轉換。比如一些常用的:
-
1.url: 會判斷這個參數的值是否是一個url,如果不是,那么就會拋出異常
-
2.regex: 正則表達式
-
3.date: 將這個字符串轉換為 datetime.date數據類型。如果轉換不成功,則會拋出一個異常
-
-
-
4.輸出字段:
-
對於一個視圖函數,你可以指定好一些字段用於返回。以后可以使用ORM模型或者自定義的模型的時候,他會自動的獲取模型中的相應的字段,生成json數據,然后再返回給客戶端。這其中需要導入 flask_restful.marshal_with裝飾器。並且需要寫一個字典,來指示需要返回的字段,以及該字段的數據類型。示例代碼如下
-
+ from flask_restful import fields + class ProfileView(Resource): + 定義好返回給前端的參數 + resource_fields = { + 'username' : fields.String, + 'age' : fields.Integer, + 'school': fields.String + } + #restful規范中, 要求,定義好了返回的參數 + #即使這個參數沒有值,也應該返回,返回一個None回去 + @marshal_with(resource_fields) + def get(self,use_id): + user = User.query.get(user_id) + return user
-
-
在get方法中,返回user的時候,flask_restful會自動的讀取user模型上的username以及age還有school屬性。組裝成一個json格式的字符串返回給客戶端
-
-
5.重命名屬性:
-
很多時候你面向公眾的字段名稱是不同於內部的屬性名。使用attribute可以配置這種映射。比如現在想要返回user.school中的值,但是在返回給外面的時候,想以education返回回去,那么可以這樣寫
-
+ resource_fields = { + 'education': fields.String(attribute = 'school') + }
-
-
-
6.默認值
-
在返回一些字段的時候,有時候可能沒有值,那么這時候可以在指定fields的時候給定一個默認值,示例代碼如下:
-
+ resource_fields = { + 'age' : fields.Integer(default = 18) + }
-
-
-
7.復雜結構:
-
有時候想要在返回的數據格式中,形成比較復雜的結構。那么可以使用一些特殊的字段來實現。比如要在一個字段中放置一個列表,那么可以使用fields.List,比如在一個字段下面又是一個字典,那么可以使用fields.Nested.以下將講解下復雜結構的用法:
-
class ProfileView(Resource): + resource_fields = { + 'username': fields.String, + 'age': fields.Integer, + 'school': fields.String, + 'tags': fields.List(fields.String), + 'more': fields.Nested({ + • 'signature': fields.String + }) + }
-
-
-
8.Flask-rsetful注意事項
-
1.在藍圖中,如果使用'flask-restful',那么在創建Api對象的時候,就不要再使用app了,而是使用藍圖。
-
2.如果在'flask-restful'的視圖中想要返回'html'代碼,或者 是模板,那么就應該使用'api.representation'這個裝飾器來定義一個函數,在這個函數中,應該對'html'代碼進行一個封裝,再返回。示例代碼如下
-
@api.representation('text/html') #這個裝飾器的作用是一旦監聽到restful里面傳入了一個模板,就會執行下面的output_html函數 def output_html(data,code,headers): print(data) data是html模板里面的所有代碼 #再representation裝飾的函數中,必須返回一個Response對象 resp = make_response(data) return resp class ListView(Resource): def get(self): return render_template('index.html') api.add_resource(ListView,'/list/',endpoint = 'list')
-
-
-