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
})
}