用 Flask 來寫個輕部落格 (32) — 使用 Flask-RESTful 來構建 RESTful API 之一
目錄
前文列表
擴充套件閱讀
RESTful API
REST(Representational State Transfer):是一種軟體架構的設計風格,而不是一種標準。主要用於 C/S 架構的軟體設計,也能很好的支援 B/S 架構,為軟體設計提供了一組原則和約束條件,但這些原則和約束的條件均不具有標準性。所以 REST 可以理解為是一組沒有嚴格標準的架構約束條件和設計原則。而滿足 REST 風格的應用或設計,就是 RESTful.
API: 為外部提供了可以訪問應用程式內容資料資源和業務資源的介面, 並且這個介面應該是統一的, 不依賴於硬體平臺/軟體作業系統/程式語言的.
REST 原則
無狀態原則
REST 具有通過 HTTP/HTTPS(無狀態傳輸協議) 直接傳輸資料(XML/JSON)的特性, 所以 C/S 或 B/S 之間的互動請求是無狀態的. 相對的, 在 <<用 Flask 來寫個輕部落格>> 系列博文中 Flask-Login 的實現, 其需要通過 session(Server) 和 cookie(Browser/client) 結合來實現在伺服器端或客戶端中儲存使用者的身份和登入狀態, 以此來實現不同的使用者在不同的頁面中可以具有不同訪問許可權的效果. REST 會使用另外的方式來這個目的, 例如 Openstack 中的 Keystone 認證中介軟體.
面向資源
資源以 URI(統一資源識別符號) 的形式向外部公開, 以 URL(統一資源定位器) 的形式來訪問獲取. 大概而言, 伺服器端 Application 的所有概念都可以定義為一種資源. 使用 URL/URI 能夠更好的契合 HTTP/HTTPS 協議, 結合 HTTP/HTTP 協議的內建 Methods(GET/POST/PUT/DELETE) 可能非常方便的實現對資源的 CRUD 資料操作, 除此之外還能夠自定義出不同的 action 方法並將其繫結到不同的 URL 中來擴充套件請求的型別, 實現了不僅限於資源的業務邏輯操作. EG. Openstack Nova 中的資源 server, 其含有的 ../os-start, ../os-stop 等 URL, 對應了 啟動/關閉 虛擬機器的業務操作. 總的來說, 每個資源都使用唯一的 URI 標識, 而資源的 URL 就是 HTTP 方法呼叫的目標.
URI: protocol://hostname[:port]/path
定義了某一類資源
URL: protocol://hostname[:port]/path/[;parameters][?query]#fragment
定義了某一個具體的資源單位
所以 URL 一般都理解為 URI 的子集.
RESTful API 的優勢
基於狀態與基於無狀態 service 在分散式系統中的區別與理解:
(因水平問題, 並不嚴謹, 僅為當下的理解, 歡迎指正)
前者, 客戶端的 Cookie 中儲存了 session_id, 如果在伺服器中該 session_id 對應的 Session 仍然存在的話將會由該 Session 來繼續維護使用者請求的狀態等公共資訊. 但問題是, 如果在這個過程中該伺服器宕機的話, 則需要重新在另外一臺伺服器中新建一個 Session 並與客戶端建立再次連線並生成 Cookie, 顯然在分散式系統中這個過程是比較無謂. 這就是基於狀態的 Web service 的分散式系統的弊端, 所有的伺服器都需要維護使用者請求狀態. 在這個前提下, 提出了類似於 LDAP(使用者資訊集中管理伺服器) 這樣的狀態集中管理機制, 由單獨的一臺或一類伺服器或服務來為整個分散式系統提供身份鑑權功能模組. 那麼其先決條件當然就是, 所有的使用者請求都必須是無狀態的, 不再有所有的伺服器都維護著使用者請求狀態等公共資訊的情況發生. 而且還需要引入別的實現方式來滿足這一方面的需求, 在 Openstack 中就引入了 Keystone 身份認證服務. 這樣做的好處還在於改善了分散式系統的可靠性以及可伸縮性.
所以 RESTful API 的優勢在於:
- 解耦了客戶端和伺服器
- 高可靠
- 易擴充套件
- 不依賴與平臺和語言
- 簡單輕量
REST 約束
注意: 這裡的約束是針對這次的 blog 專案所設計的, 並部一定完全設用於所有應用場景, 需要結合實際進行改進, 所以不應滿足與使用, 而是要在不斷的實踐中加深對 REST 的理解和累積經驗.
客戶端和服務端關心的業務是完全分離的, 前者不能處理資料的持久化, 後者不能處理與使用者頁面表現層相關的邏輯. 在 blog application 中, 整個專案都會作為服務端.
服務端是無狀態的, 請求與響應的過程中服務端不會保留任何的 session 等狀態資訊. 處理請求所需要的資訊都會被儲存在客戶端中, 或者被每一次單獨的請求所攜帶. Flask Application 接受的每一個請求都可以攜帶儲存在客戶端中的 cookie 資料, 再交由服務端解析並以此判斷許可權等資訊, 但不保留.
服務端公佈的所有資源都必須保證統一的介面形似, 即 :
- 介面必須是基於資源的
- 不直接返回資料庫中的資料而是包裝成為 JSON 或 XML 等形式後返回
- 所有資源都應用一致的包裝形式
- 服務端返回的資料應該足夠完整能夠滿足客戶端的業務需求
允許中間層的存在, EG. 能夠支援使用 負載均衡/代理/快取 等中間層服務
返回正確的 HTTP/HTTPS 狀態碼