REST - Representational State Transfer - 表述性狀態轉移 (資源在網絡中以某種形式進行狀態轉移)
REST風格特點:
1.資源
所謂"資源",就是網絡上的一個實體,或者說是網絡上的一個具體信息。它可以是一段文本、一張圖片、一首歌曲、一種服務,總之就是一個具體的實在。資源總要通過某種載體反應其內容,文本可以用txt格式表現,也可以用HTML格式、XML格式表現,甚至可以采用二進制格式;圖片可以用JPG格式表現,也可以用PNG格式表現;JSON是現在最常用的資源表示格式。
結合我的開發實踐,我對資源和數據理解如下:
資源是以json(或其他Representation)為載體的、面向用戶的一組數據集,資源對信息的表達傾向於概念模型中的數據:
資源總是以某種Representation為載體顯示的,即序列化的信息
常用的Representation是json(推薦)或者xml(不推薦)等
Represntation 是REST架構的表現層
2.統一接口
RESTful架構風格規定,數據的元操作,即CRUD(create, read, update和delete,即數據的增刪查改)操作,分別對應於HTTP方法:GET用來獲取資源,POST用來新建資源(也可以用於更新資源),PUT用來更新資源,DELETE用來刪除資源,這樣就統一了數據操作的接口,僅通過HTTP方法,就可以完成對數據的所有增刪查改工作。
Verd | 描述 |
HEAD(SELECT) | 只獲取某個資源的頭部信息 |
GET(SELECT) | 獲取資源 |
POST(CREATE) | 創建資源 |
PATCH(UPDATE) | 更新資源的部分屬性(很少用,一般用POST代替) |
PUT(UPDATE) | 更新資源,客戶端需要提供新建資源的所有屬性 |
DELETE(DELETE) | 刪除資源 |
3.URI
可以用一個URI(統一資源定位符)指向資源,即每個URI都對應一個特定的資源。要獲取這個資源,訪問它的URI就可以,因此URI就成了每一個資源的地址或識別符。
一般的,每個資源至少有一個URI與之對應,最典型的URI即URL。
4.無狀態
所謂無狀態的,即所有的資源,都可以通過URI定位,而且這個定位與其他資源無關,也不會因為其他資源的變化而改變。有狀態和無狀態的區別,舉個簡單的例子說明一下。如查詢員工的工資,如果查詢工資是需要登錄系統,進入查詢工資的頁面,執行相關操作后,獲取工資的多少,則這種情況是有狀態的,因為查詢工資的每一步操作都依賴於前一步操作,只要前置操作不成功,后續操作就無法執行;如果輸入一個url即可得到指定員工的工資,則這種情況是無狀態的,因為獲取工資不依賴於其他資源或狀態,且這種情況下,員工工資是一個資源,由一個url與之對應,可以通過HTTP中的GET方法得到資源,這是典型的RESTful風格。
5. stateless-auth
由於RESTful風格的服務是無狀態的,認證機制尤為重要。例如上文提到的員工工資,這應該是一個隱私資源,只有員工本人或其他少數有權限的人有資格看到,如果不通過權限認證機制對資源做一層限制,那么所有資源都以公開方式暴露出來,這是不合理的,也是很危險的。
認證機制解決的問題是,確定訪問資源的用戶是誰;權限機制解決的問題是,確定用戶是否被許可使用、修改、刪除或創建資源。權限機制通常與服務的業務邏輯綁定,因此權限機制需要在每個系統內部定制,而認證機制基本上是通用的,常用的認證機制包括 session auth(即通過用戶名密碼登錄),basic auth,token auth和OAuth,服務開發中常用的認證機制為后三者。
1. Basic Auth是配合RESTful API 使用的最簡單的認證方式,只需提供用戶名密碼即可,但由於有把用戶名密碼暴露給第三方客戶端的風險,在生產環境下被使用的越來越少。因此,在開發對外開放的RESTful API時,盡量避免采用Basic Auth
2. Token Auth並不常用,它與Basic Auth的區別是,不將用戶名和密碼發送給服務器做用戶認證,而是向服務器發送一個事先在服務器端生成的token來做認證。因此Token Auth要求服務器端要具備一套完整的Token創建和管理機制,該機制的實現會增加大量且非必須的服務器端開發工作,也不見得這套機制足夠安全和通用,因此Token Auth用的並不多。
3. OAuth(開放授權)是一個開放的授權標准,允許用戶讓第三方應用訪問該用戶在某一web服務上存儲的私密的資源(如照片,視頻,聯系人列表),而無需將用戶名和密碼提供給第三方應用。OAuth允許用戶提供一個令牌,而不是用戶名和密碼來訪問他們存放在特定服務提供者的數據。每一個令牌授權一個特定的第三方系統(例如,視頻編輯網站)在特定的時段(例如,接下來的2小時內)內訪問特定的資源(例如僅僅是某一相冊中的視頻)。這樣,OAuth讓用戶可以授權第三方網站訪問他們存儲在另外服務提供者的某些特定信息,而非所有內容。正是由於OAUTH的嚴謹性和安全性,現在OAUTH已成為RESTful架構風格中最常用的認證機制,和RESTful架構風格一起,成為企業級服務的標配。目前OAuth已經從OAuth1.0發展到OAuth2.0,但這二者並非平滑過渡升級,OAuth2.0在保證安全性的前提下大大減少了客戶端開發的復雜性,因此,Gevin建議在實戰應用中采用OAuth2.0認證機制。現在網上關於OAuth的資料非常豐富,也有大量開源的第三方庫實現了OAuth機制,不熟悉OAuth的同學從OAuth官網入手即可。
6.冪等性
一次請求和多次請求,資源的狀態是一樣。無論調用多少次都不會產生不同副作用(數據變更)
比如GET和HEAD ,不論你請求多少次,資源還是在那里
DELETE和PUT也是等冪的,因為對同一個資源刪除一次或者多次,結果是一樣的,就是資源被刪除
冪等:
GET: get用於獲取資源,不管調用多少次接口,返回結果保持不變,不會改變資源
PUT: put用於更新資源,沒有的話則執行創建操作
第一次調用 PUT /tickets/11 , 后台創建 /tickets/11 (幫我看下11號票在不在,在的話更新下狀態,不在的話創建下)
第二次調用 PUT /tickets/11 , 后台更新 /tickets/11 (幫我看下11號票在不在,在的話更新下狀態,不在的話創建下)
由於兩次請求攜帶的數據是一樣的,所以不論請求多少次,最終的結果都是后台存在這么一個資源(創建或更新)
DELETE: delete用於刪除資源,會將資源從后台刪除。如:
第一次調用 DELETE /tickets/11 , 后台刪除 /tickets/11對應的數據信息 (11號票我不要了,幫我刪除下吧)
第二次調用 DELETE /tickets/11 , 后台判斷 /tickets/11不存在,無操作(11號票我不記得有沒有刪除,幫我刪除下吧)
非冪等:
POST: post用於創建資源,每次調用都會創建一個新的資源
第一次調用 POST /tickets ,后台產生 /tickets/1 這么一個資源(我要新增一張票)
第二次調用 POST /tickets , 后台產生 /tickets/2 這么一個資源(我要再新增一張票)
所以設計Restful API的時候,GET,HEAD, PUT, DELETE一定要設計成冪等。
由於網絡是不可靠的,安全性和冪等性就顯得特別重要。如果一次請求,服務器收到處理以后,客戶端沒有收到相應,客戶端會再次請求,如果沒有等冪性保障,就會發生意想不到的問題