Flask-Restful詳解
Restful API規範
restful api
是用於在前端與後臺進行通訊的一套規範。使用這個規範可以讓前後端開發變得更加輕鬆。以下將討論這套規範的一些設計細節。
協議:
採用http
或者https
協議。
資料傳輸格式:
資料之間傳輸的格式應該都使用json
,而不使用xml
。
url連結:
url連結中,不能有動詞,只能有名詞。並且對於一些名詞,如果出現複數,那麼應該在後面加s
。
比如:獲取文章列表,應該使用`/articles/`,而不應該使用/get_article/
HTTP請求的方法:
GET
:從伺服器上獲取資源。POST
:在伺服器上新建立一個資源。PUT
:在伺服器上更新資源。(客戶端提供所有改變後的資料)PATCH
:在伺服器上更新資源。(客戶端只提供需要改變的屬性)DELETE
:從伺服器上刪除資源。
示例如下:
- GET /users/:獲取所有使用者。
- 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外掛
通過
pip install flask-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):
return {"username":"donghao"}
api.add_resource(IndexView,'/',endpoint='index')
注意事項:
endpoint
是用來給url_for
反轉url
的時候指定的。如果不寫endpoint
,那麼將會使用檢視的名字的小寫來作為endpoint
。add_resource
的第二個引數是訪問這個檢視函式的url
,這個url
可以跟之前的route
一樣,可以傳遞引數。並且還有一點不同的是,這個方法可以傳遞多個url
來指定這個檢視函式。
引數解析:
Flask-Restful
外掛提供了類似WTForms
來驗證提交的資料是否合法的包,叫做reqparse
。以下是基本用法:
parser = reqparse.RequestParser()
parser.add_argument('username',type=str,help='請輸入使用者名稱')
args = parser.parse_args()
add_argument
可以指定這個欄位的名字,這個欄位的資料型別等。以下將對這個方法的一些引數做詳細講解:
default
:預設值,如果這個引數沒有值,那麼將使用這個引數指定的值。required
:是否必須。預設為False,如果設定為True
,那麼這個引數就必須提交上來。type
:這個引數的資料型別,如果指定,那麼將使用指定的資料型別來強制轉換提交上來的值。choices
:選項。提交上來的值只有滿足這個選項中的值才符合驗證通過,否則驗證不通過。help
:錯誤資訊。如果驗證失敗後,將會使用這個引數指定的值作為錯誤資訊。trim
:是否要去掉前後的空格。
其中的type
,可以使用python
自帶的一些資料型別,也可以使用flask_restful.inputs
下的一些特定的資料型別來強制轉換。比如一些常用的:
url
:會判斷這個引數的值是否是一個url,如果不是,那麼就會丟擲異常。regex
:正則表示式。date
:將這個字串轉換為datetime.date
資料型別。如果轉換不成功,則會丟擲一個異常。
輸出欄位:
對於一個檢視函式,你可以指定好一些欄位用於返回。以後可以使用ORM模型或者自定義的模型的時候,他會自動的獲取模型中的相應的欄位,生成json
資料,然後再返回給客戶端。這其中需要匯入flask_restful.marshal_with
裝飾器。並且需要寫一個字典,來指示需要返回的欄位,以及該欄位的資料型別。示例程式碼如下:
class ProfileView(Resource):
resource_fields = {
'username': fields.String,
'age': fields.Integer,
'school': fields.String
}
@marshal_with(resource_fields)
def get(self,user_id):
user = User.query.get(user_id)
return user
在get
方法中,返回user
的時候,flask_restful
會自動的讀取user
模型上的username
以及age
還有school
屬性。組裝成一個json
格式的字串返回給客戶端。
重新命名屬性:
很多時候你面向公眾的欄位名稱是不同於內部的屬性名。使用 attribute可以配置這種對映。比如現在想要返回user.school
中的值,但是在返回給外面的時候,想以education
返回回去,那麼可以這樣寫:
resource_fields = {
'education': fields.String(attribute='school')
}
預設值:
在返回一些欄位的時候,有時候可能沒有值,那麼這時候可以在指定fields
的時候給定一個預設值,示例程式碼如下:
resource_fields = {
'age': fields.Integer(default=18)
}
複雜結構:
有時候想要在返回的資料格式中,形成比較複雜的結構。那麼可以使用一些特殊的欄位來實現。比如要在一個欄位中放置一個列表,那麼可以使用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
})
}