Restful風格學習總結

非RESTful風格問題

七宗罪的第一條,混亂。  

   一萬個人心裏有一萬個Url的命名規則,Url是統一資源定位符,重點是資源。而很多人卻把它當成了萬金油,每一個獨立的虛擬的網頁都可以隨意使用,各種操作都能夠迭加。這是混亂的來源之一。 
比如:

https://localhost:8080/myweb/getUserById?id=1
https://localhost:8080/myweb/user/getById?id=1
https://localhost:8080/myweb/x/y?id=1

第二條,貪婪。

  有狀態和無狀態全部混在一起。特別是在購物車或者是登錄的應用中,經常刷新就丟失帶來的用戶體驗簡直棒棒噠。每一個請求並不能單獨的響應一些功能,很多的功能混雜在一起裏。這是人性貪婪的本質,也是各種Hack的起源,只要能夠把問題解決掉,總會有人用他認爲最方便的方式去解決問題,比如說汽車門把手壞掉了直接系根繩子當把手,emmmm這樣確實很棒啊。 
   
第三條,無序。

  返回的結果往往是很隨意,各種錯誤信息本來就是用Http的狀態碼構成的,可是很多人還是喜歡把錯誤信息返回在返回值中。最常見的就是Code和Message,當然對於這一點,我個人是保留疑問的,我的觀點是,Http本身的錯誤和服務器的內部錯誤還是需要在不斷層面分開的,不能混在一起。可是在大神眼裏並非如此。

對比
https://localhost:8080/myweb/getDogs --> GET /rest/api/dogs 獲取所有小狗狗 
https://localhost:8080/myweb/addDogs --> POST /rest/api/dogs 添加一個小狗狗 
https://localhost:8080/myweb/updateDogs/:dog_id --> PUT /rest/api/dogs/:dog_id 修改一個小狗狗 
https://localhost:8080/myweb/deleteDogs/:dog_id --> DELETE /rest/api/dogs/:dog_id 刪除一個小狗狗

左邊是我們寫的,而且後臺我們可能會寫出很多返回值,而且各種各樣的,比如 
https://localhost:8080/myweb/addDogs

操作成功 或者 1
1
或者

操作失敗 或者 0
1
這還要我們自己去解析,還要前端和後端去協商你返回的0是啥意識啊。但是REST返回值是標準的,比如

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: xxx

{
   "url" : "/api/categories/1",
   "label" : "Food",
   "items_url" : "/api/items?category=1",
   "brands" : [
         {
            "label" : "友臣",
            "brand_key" : "32073",
            "url" : "/api/brands/32073"
         }, {
            "label" : "樂事",
            "brand_key" : "56632",
            "url" : "/api/brands/56632"
         }
         ...
   ]
}



格式固定,第一行永遠是操作失敗或者成功的狀態碼,第二行是返回的類型,第三行內容的長度,第五行開始是內容。

這樣我只需寫一個程序解析返回的信息就可以了,可以重用,但是我們上面傳統的不僅僅要協商,還有有不同的解析程序,稍微改變,就不能正常使用了。所以rest的明顯更加通用。

 

列子2

1、獲取文章

請求:
GET /blog/post/{postId} HTTP/1.1

響應:
HTTP/1.1 200 OK
{
    "title": "foobar",
    "content": "foobar",
    "comments": ["", "", ""]
}

2、發佈文章

請求:
POST /blog/post HTTP/1.1
{
    "title": "foobar",
    "content": "foobar",
    "comments": ["", "", ""]
}

響應:
HTTP/1.1 201 CREATED



規則

GET    用來獲取資源,
POST  用來新建資源(也可以用於更新資源),
PUT    用來更新資源,
DELETE  用來刪除資源


例子

DELETE http://api.qc.com/v1/friends: 刪除某人的好友 (在http parameter指定好友id)
POST http://api.qc.com/v1/friends: 添加好友UPDATE 
PUT http://api.qc.com/v1/profile: 更新個人資料

 

是什麼?

REST是一個標準,一種規範,遵循REST風格可以使開發的接口通用,便於調用者理解接口的作用。
 


概念


REST 是面向資源的,這個概念非常重要,而資源是通過 URI 進行暴露。 
URI 的設計只要負責把資源通過合理方式暴露出來就可以了。對資源的操作與它無關,操作是通過 HTTP動詞來體現,所以REST 通過 URI 暴露資源時,會強調不要在 URI 中出現動詞。

比如:左邊是錯誤的設計,而右邊是正確的

GET /rest/api/getDogs --> GET /rest/api/dogs 獲取所有小狗狗 
GET /rest/api/addDogs --> POST /rest/api/dogs 添加一個小狗狗 
GET /rest/api/editDogs/:dog_id --> PUT /rest/api/dogs/:dog_id 修改一個小狗狗 
GET /rest/api/deleteDogs/:dog_id --> DELETE /rest/api/dogs/:dog_id 刪除一個小狗狗
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: xxx

{
   "url" : "/api/categories/1",
   "label" : "Food",
   "items_url" : "/api/items?category=1",
   "brands" : [
         {
            "label" : "友臣",
            "brand_key" : "32073",
            "url" : "/api/brands/32073"
         }, {
            "label" : "樂事",
            "brand_key" : "56632",
            "url" : "/api/brands/56632"
         }
         ...
   ]
}



REST很好地利用了HTTP本身就有的一些特徵,如HTTP動詞、HTTP狀態碼、HTTP報頭等等 
REST API 是基於 HTTP的,所以你的API應該去使用 HTTP的一些標準。這樣所有的HTTP客戶端(如瀏覽器)才能夠直接理解你的API(當然還有其他好處,如利於緩存等等)。REST 實際上也非常強調應該利用好 HTTP本來就有的特徵,而不是隻把 HTTP當成一個傳輸層這麼簡單了。

看這個響應,包含了http裏面的狀態碼等信息。還會有http的一些報頭。

Authorization 認證報頭 
Cache-Control 緩存報頭 
Cnotent-Type  消息體類型報頭 
......


REST 系統的特徵

 

  • 客戶-服務器(Client-Server),提供服務的服務器和使用服務的客戶需要被隔離對待。
  • 無狀態(Stateless),來自客戶的每一個請求必須包含服務器處理該請求所需的所有信息。換句話說,服務器端不能存儲來自某個客戶的某個請求中的信息,並在該客戶的其他請求中使用。
  • 可緩存(Cachable),服務器必須讓客戶知道請求是否可以被緩存。(Ross:更詳細解釋請參考 理解本真的REST架構風格 以及 StackOverflow 的這個問題 中對緩存的解釋。)
  • 分層系統(Layered System),服務器和客戶之間的通信必須被這樣標準化:允許服務器和客戶之間的中間層(Ross:代理,網關等)可以代替服務器對客戶的請求進行迴應,而且這些對客戶來說不需要特別支持。
  • 統一接口(Uniform Interface),客戶和服務器之間通信的方法必須是統一化的。(Ross:GET,POST,PUT.DELETE, etc)
  • 支持按需代碼(Code-On-Demand,可選),服務器可以提供一些代碼或者腳本(Ross:Javascrpt,flash,etc)並在客戶的運行環境中執行。這條準則是這些準則中唯一不必必須滿足的一條。(Ross:比如客戶可以在客戶端下載腳本生成密碼訪問服務器。)

詳細解釋

無狀態(Stateless)

   所謂無狀態的,即所有的資源,都可以通過URI定位,而且這個定位與其他資源無關,也不會因爲其他資源的變化而改變。有狀態和無狀態的區別,舉個簡單的例子說明一下。如查詢員工的工資,如果查詢工資是需要登錄系統,進入查詢工資的頁面,執行相關操作後,獲取工資的多少,則這種情況是有狀態的,因爲查詢工資的每一步操作都依賴於前一步操作,只要前置操作不成功,後續操作就無法執行;如果輸入一個url即可得到指定員工的工資,則這種情況是無狀態的,因爲獲取工資不依賴於其他資源或狀態,且這種情況下,員工工資是一個資源,由一個url與之對應,可以通過HTTP中的GET方法得到資源,這是典型的RESTful風格。

 è¿éåå¾çæè¿°

 è¿éåå¾çæè¿°

統一接口(Uniform Interface)

  RESTful架構風格規定,數據的元操作,即CRUD(create, read, update和delete,即數據的增刪查改)操作,分別對應於HTTP方法:GET用來獲取資源,POST用來新建資源(也可以用於更新資源),PUT用來更新資源,DELETE用來刪除資源,這樣就統一了數據操作的接口,僅通過HTTP方法,就可以完成對數據的所有增刪查改工作。

即:

GET(SELECT):從服務器取出資源(一項或多項)。
POST(CREATE):在服務器新建一個資源。
PUT(UPDATE):在服務器更新資源(客戶端提供完整資源數據)。
PATCH(UPDATE):在服務器更新資源(客戶端提供需要修改的資源數據)。
DELETE(DELETE):從服務器刪除資源。



演化


https://zhuanlan.zhihu.com/p/30396391?group_id=937244108725641216

優點&缺點


優點:

  • 適合開放性高的API。這幾年的由於移動互聯網流行使得前端設備多樣化,業界急需一種統一的機制來規範API設計,使得API適用於各種各樣的前端設備,REST符合這種需求。

  • 行爲和資源分離,更容易理解

  • 提出使用版本號(例如v1、v2),更加規範。

缺點

  • 對後端開發人員要求高,業務邏輯有時難以被抽象爲資源的增刪改查。(例如批量刪除數據,等複雜的邏輯)。

  • 對前端開發人員不友好,API粒度較粗,難以查詢符合特殊要求的數據,同樣的業務要比普通的API需要更多次HTTP請求。

 

參考文章: 

https://blog.csdn.net/qq_21383435/article/details/80032375 
https://www.zhihu.com/question/28557115 
https://blog.igevin.info/posts/restful-architecture-in-general/
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章