對前后端分離設計模式的理解總結(部分Django描述)

最近對前后端分離設計模式的理解總結:

為什么要做前后端分離:

  • 有些人會說:因為職責明確,因為不再用模板做視圖層 render HTML,后端不用自己寫前端就會輕松些... 這些大多說的不錯,但還是比較表象,主要的原因其實是 源于需求變化

    在現代web開發中,我們對于前端的需求越來越復雜,我們需要 PC端瀏覽器、手機端瀏覽器 、Android APP 和 iPhone APP 、微信小程序等多種需求。

    由于我們前端可能涉及設計到的頁面種類越來越多,而 vue、angular、react 等前端框架越來越好的支持:“ Code once,run everywhere. ”,所以前端的開發漸漸獨立、并更為體系化。

    故而曾經那種單憑一套模板渲染頁面的方法似乎太局限了。

  • 而一旦采用 前后端分離 的模式,并且采用 restful 設計規范,那么后端就只需要提供數據 API 接口即可,后端只需要長期維護這一套代碼就行了。

Django 的 FBV & CBV

FBV:Function base view 基于方法的視圖

CBV:Class base view 基于類的視圖

在我最開始嘗試用 Flask 框架遵循 Restful 規范按路由設計接口時,常常有這樣幾個疑問和思考:

  • 我的需求這么多,難道沒一個都要設計一個接口嗎?這樣方便維護嗎?
  • 比如一個接口可能有 GET、POST 或是 PUT 等類型的請求,我難道每次都要寫一個選擇分支:if request.method == ' ... ': 才可以嗎?

所以之后我了解到,其實是我沒有了解 FBV 與 CBV 的概念。

正所謂:類就是 把數據封裝進對象里 ,并賦予對象 行為 的能力。

所以我們完全可以把一個需求的接口封裝成為一個類:

from django.views import View

class UserView(View): # 我們假設這是一個關于用戶的接口,django/Flask中路由也叫視圖。
        
    def get(self, request, *args, **kwargs):
        # ... 對應GET請求
        
    def post(self, request, *args, **kwargs):
        # ... 對應POST請求
        
    def put(self, request, *args, **kwargs):
        # ... 對應PUT請求
    
    def delete(self, request, *args, **kwargs):
        # ... 對應DELETE請求
        

因為繼承了 django 的 View 類,所以在默認情況下,會自動根據請求類型映射該類中對應的請求方法。

但是在所有的 python web 框架乃至一些其他語言的框架之中,對 HTTP 請求類型的方法映射都是由一個專門的反射函數來實現的

# 本身在django的源碼 base.py 中:
def dispatch(self, request, *args, **kwargs):
    # 是有這樣一個基礎的反射方法的。
    
# Override (但在我們繼承了 View 的類中,我們可以重載它試驗一下)
from django.views import View
class User(View):
    def dispatch(self, request, *args, **kwargs):
        func = getattr(self, request.method.lower()) #必須要小寫化不然映射不到我們剛才寫的四個對應方法
        ret = func(self, request, *args, **kwargs)
        return ret

    # ...下面四個方法同上

所以,總結如下:

  • CBV:基于反射實現根據請求方式不同,執行不同的方法。

    原理:URL -> view方法 -> dispatch方法(反射執行其他:GET/POST/DELETE/PUT)

另外值得一提的是:自己那個類中的 dispatch 方法中如果不自己去映射而是調用父類(django 的 View)的 dispatch 方法,另外還在前后做一些附加操作,這樣的功能跟 “裝飾器” 就很相似了。

RESTful API 設計規范

RESTful 規范是一種建議而非硬性要求,但是在前后端分離是大趨勢的當下,越來越多的程序員們開始喜歡遵照 RESTful 規范來設計后端接口。

一共有10個項目,那讓我們一起來慢慢學習吧!

  1. API與用戶的通信協議,總是使用HTTPS協議

    • 因為HTTPS比HTTP更加安全,所以在建立、部署大中型網站時企業都會選擇使用HTTPS,但是由于HTTPS需要配置專門的證書,而如果需要具備較高的認可度的證書,則需要從證書商處購買,而價格大多不便宜。
  2. 域名配置要體現自己是個 API

  3. 后端API接口請區分版本

  4. 路徑 -> 面向資源編程:

    何為面向資源編程呢?就是把互聯網上的任何東西都視為一種資源,而我們在后端對該實體描述的 API 路由都為名詞。

    而不是類似于 getUser、addUser 這樣的動詞!

    具體請看下一條 ...

  5. methods :HTTP方法

    始終記住 RESTful 設計要充分利用 HTTP協議里的 GET、POST、PUT、PATCH 和 DELETE 等 方法標志 來表達對數據的 增刪改查

    • GET /collection:返回資源對象的列表(數組)
    • GET /collection/resource:返回單個資源對象
    • POST /collection:返回新生成的資源對象
    • PUT /collection/resource:返回完整的資源對象
    • PATCH /collection/resource:返回完整的資源對象
    • DELETE /collection/resource:返回一個空文檔
  1. 對資源的條件過濾 -> 用 URL傳參 來指定過濾條件

    類似于 例如查訂單時 http://api.mall.com/orders?sortby=dectime 則是以按降序時間排列訂單...

  2. 一定要使用 狀態碼

    常見的狀態碼:

    200 系列: 成功及其附屬狀態信息

    • 200 OK - [GET]:服務器成功返回用戶請求的數據,該操作是冪等的(Idempotent)。
    • 201 CREATED - [POST/PUT/PATCH]:用戶新建或修改數據成功。
    • 202 Accepted - [*]:表示一個請求已經進入后臺排隊(異步任務)
    • 204 NO CONTENT - [DELETE]:用戶刪除數據成功。
    • ...

300 系列:重定向類

  • 例如 301 MOVED PERMANENTLY
  • ...

400 系列 :客戶端錯誤

  • 400 INVALID REQUEST - [POST/PUT/PATCH]:用戶發出的請求有錯誤,服務器沒有進行新建或修改數據的操作,該操作是冪等的。
  • 401 Unauthorized - [*]:表示用戶沒有權限(令牌、用戶名、密碼錯誤)。
  • 403 Forbidden - [*] 表示用戶得到授權(與401錯誤相對),但是訪問是被禁止的。
  • 404 NOT FOUND - [*]:用戶發出的請求針對的是不存在的記錄,服務器沒有進行操作,該操作是冪等的。
  • 406 Not Acceptable - [GET]:用戶請求的格式不可得(比如用戶請求JSON格式,但是只有XML格式)。
  • 410 Gone -[GET]:用戶請求的資源被永久刪除,且不會再得到的。
  • 422 Unprocessable entity - [POST/PUT/PATCH] 當創建一個對象時,發生一個驗證錯誤。
  • ...

500 系列: 服務端錯誤

  • 500 INTERNAL SERVER ERROR - [*]:服務器發生錯誤,用戶將無法判斷發出的請求是否成功。
  • ...

單光用 HTTP狀態碼 在實際開發中是遠遠不夠的哦!

一般還會加上一個我們自己的 code;

參見Alibaba Alipay支付寶文檔:https://docs.open.alipay.com/common/105806 code( 返回碼 )

這些自定義的返回碼大大增加了我們能夠表示的 服務對客戶端請求的響應狀態的類型。

由于狀態碼十分有限,所以一般前端大多會被要求處理 自定義的這個code。

  1. 錯誤處理

    承接上一個小段,當狀態碼是 4xx 時,應當返回錯誤信息,error 當做 key:

    {
        error:"Invalid API key!"
    }
    
  2. 以 API url 來確定返回類型!

    • GET /collection:返回資源對象的列表(數組)
    • GET /collection/resource:返回單個資源對象
    • POST /collection:返回新生成的資源對象
    • PUT /collection/resource:返回完整的資源對象
    • PATCH /collection/resource:返回完整的資源對象
    • DELETE /collection/resource:返回一個空文檔

    這樣干巴巴地說自然很難理解那個 collection 是什么意思:還是以訂單舉例:

    http://api.mall.com/orders/18924442 => orders 是復數(一般來說,數據庫中的表都是同種記錄的"集合"(collection),所以API中的名詞也應該使用復數。),我的操作目標是 訂單集合,而后面的 18924442(一個訂單 id 示例)就代表著資源對象的實體 resource!

    那么我對這個 api url 的 post 、delete 、put / patch 和 get 就分別對應了該資源的 增刪改查 接口。

  3. HypermediaAPI:

    即返回結果中提供鏈接,連向其他API方法,使得用戶不查文檔,也知道下一步應該做什么。

    比如:對于我正準備要實現的 RPZ計協 · 科丁特沃夫咖啡廳論壇 桌帖的評論列表 這件事情:

    • /coffeeComments?postid=12 第十二個咖啡桌帖的評論列表:
      [
          {
              id: '100030001',
              author: '飛翔的海貓',
              content: '你這個寫的有bug呀!'
              datetime: '2019-01-19 22:10:35',
              likes: 0
              commentsList: 'https://api.sicnurpz.online/coffeeComments?commentid=100030001'
          }
      ]
      
    • 前面的都是 評論數據類型該有的基本信息比如 評論者的昵稱、評論內容等,但為什么我要在最后加上一個 commentsList,還是個 url 地址字符串呢?

      因為這樣我就不用再在服務端去拼接 查詢該條評論的評論列表 的字符串了! 提高了后端接口處理的效率,在現代服務器存儲量充足的情況下,數據存儲空間 換 網絡響應時間自然是不虧的啦!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,196評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,688評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,456評論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,955評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,195評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,725評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,608評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,802評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,048評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,424評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,762評論 2 372

推薦閱讀更多精彩內容