REST介绍以及常用的返回状态码
簡介
Representational State Transfer 簡稱 REST 描述了一個架構樣式的網絡系統。REST 指的是
一組架構約束條件和原則。滿足這些約束條件和原則的應用程序或設計就是 RESTful。
概念:
資源(Resources) REST是”表現層狀態轉化”,其實它省略了主語。”表現層”其實指的是”資源”的”表現層”。
那么什么是資源呢?就是我們平常上網訪問的一張圖片、一個文檔、一個視頻等。這些資源我們通過URI來定位,也就是一個URI表示一個資源。
表現層(Representation)
資源是做一個具體的實體信息,他可以有多種的展現方式。而把實體展現出來就是表現層,例如一個txt文本信息,他可以輸出成html、json、xml等格式,一個圖片他可以jpg、png等方式展現,這個就是表現層的意思。
URI確定一個資源,但是如何確定它的具體表現形式呢?應該在HTTP請求的頭信息中用Accept和Content-Type字段指定,這兩個字段才是對”表現層”的描述。
狀態轉化(State Transfer)
訪問一個網站,就代表了客戶端和服務器的一個互動過程。在這個過程中,肯定涉及到數據和狀態的變化。而HTTP協議是無狀態的,那么這些狀態肯定保存在服務器端,所以如果客戶端想要通知服務器端改變數據和狀態的變化,肯定要通過某種方式來通知它。
URI格式規范
URI中盡量使用連字符”-“代替下劃線”_”的使用
URI中統一使用小寫字母
URI中不要包含文件(腳本)的擴展名
資源的原型
文檔(Document)
1 |
文檔是資源的單一表現形式,可以理解為一個對象,或者數據庫中的一條記錄。在請求文檔時, |
集合(Collection)
1 |
集合可以理解為是資源的一個容器(目錄),我們可以向里面添加資源(文檔)。例如: |
倉庫(Store)
1 |
倉庫是客戶端來管理的一個資源庫,客戶端可以向倉庫中新增資源或者刪除資源。 |
控制器(Controller)
1 |
控制器資源模型,可以執行一個方法,支持參數輸入,結果返回。 是為了除了標準操作: |
把動作轉換成資源
1 |
把動作轉換成可以執行 CRUD 操作的資源, github 就是用了這種方法。 |
URI命名規范
文檔(Document)類型的資源用名詞(短語)單數命名
集合(Collection)類型的資源用名詞(短語)復數命名
倉庫(Store)類型的資源用名詞(短語)復數命名
控制器(Controller)類型的資源用動詞(短語)命名
URI中有些字段可以是變量,在實際使用中可以按需替換
1 |
例如一個資源URI可以這樣定義: |
CRUD的操作不要體現在URI中,HTTP協議中的操作符已經對CRUD做了映射。
1 |
CRUD是創建,讀取,更新,刪除這四個經典操作的簡稱 |
URI的query字段
在REST中,query字段一般作為查詢的參數補充,也可以幫助標示一個唯一的資源。但需要注意的是,
作為一個提供查詢功能的URI,無論是否有query條件,我們都應該保證結果的唯一性,
一個URI對應的返回數據是不應該被改變的(在資源沒有修改的情況下)。
HTTP中的緩存也可能緩存查詢結果。
Query參數可以作為Collection或Store類型資源的過濾條件來使用 例如:
1 |
GET /users //返回所有用戶列表 |
Query參數可以作為Collection或Store資源列表分頁標示使用
1 |
如果是一個簡單的列表操作,可以這樣設計: |
HTTP請求方法的使用
GET方法用來獲取資源
PUT方法可用來新增/更新Store類型的資源
PUT方法可用來更新一個資源的全部屬性,使用時傳遞所有屬性的值,即使有的值沒有改變
PATCH方法更新資源的部分屬性。因為 PATCH 比較新,而且規范比較復雜,所以真正實現的比較少,
一般都是用 POST 替代
POST方法可用來創建一個資源
POST方法可用來觸發執行一個Controller類型資源
DELETE方法用于刪除資源
HTTP響應狀態碼的使用
200 (“OK”) 用于一般性的成功返回
200 (“OK”) 不可用于請求錯誤返回
201 (“Created”) 資源被創建
202 (“Accepted”) 用于Controller控制類資源異步處理的返回,僅表示請求已經收到。
對于耗時比較久的處理,一般用異步處理來完成
204 (“No Content”) 此狀態可能會出現在PUT、POST、DELETE的請求中,一般表示資源存在,
但消息體中不會返回任何資源相關的狀態或信息。
301 (“Moved Permanently”) 資源的URI被轉移,需要使用新的URI訪問
302 (“Found”) 不推薦使用,此代碼在HTTP1.1協議中被303/307替代。
我們目前對302的使用和最初HTTP1.0定義的語意是有出入的,應該只有在GET/HEAD方法下,
客戶端才能根據Location執行自動跳轉,而我們目前的客戶端基本上是不會判斷原請求方法的,
無條件的執行臨時重定向
303 (“See Other”) 返回一個資源地址URI的引用,但不強制要求客戶端獲取該地址的狀態(訪問該地址)
304 (“Not Modified”) 有一些類似于204狀態,服務器端的資源與客戶端最近訪問的資源版本一致,
并無修改,不返回資源消息體。可以用來降低服務端的壓力
307 (“Temporary Redirect”) 目前URI不能提供當前請求的服務,臨時性重定向到另外一個URI。
在HTTP1.1中307是用來替代早期HTTP1.0中使用不當的302
400 (“Bad Request”) 用于客戶端一般性錯誤返回, 在其它4xx錯誤以外的錯誤,也可以使用400,
具體錯誤信息可以放在body中
401 (“Unauthorized”) 在訪問一個需要驗證的資源時,驗證錯誤
403 (“Forbidden”) 一般用于非驗證性資源訪問被禁止,例如對于某些客戶端只開放部分API的訪問權限,
而另外一些API可能無法訪問時,可以給予403狀態
404 (“Not Found”) 找不到URI對應的資源
405 (“Method Not Allowed”) HTTP的方法不支持,例如某些只讀資源,可能不支持POST/DELETE。
但405的響應header中必須聲明該URI所支持的方法
406 (“Not Acceptable”) 客戶端所請求的資源數據格式類型不被支持,
例如客戶端請求數據格式為application/xml,但服務器端只支持application/json
409 (“Conflict”) 資源狀態沖突,例如客戶端嘗試刪除一個非空的Store資源
412 (“Precondition Failed”) 用于有條件的操作不被滿足時
415 (“Unsupported Media Type”) 客戶所支持的數據類型,服務端無法滿足
429 (“Too Many Requests”) 客戶端在規定的時間里發送了太多請求,在進行限流的時候會用到
500 (“Internal Server Error”) 服務器端的接口錯誤,此錯誤于客戶端無關
HTTP Headers
Content-Type 標示body的數據格式
Content-Length body 數據體的大小,客戶端可以根據此標示檢驗讀取到的數據是否完整,
也可以通過Header判斷是否需要下載可能較大的數據體
Last-Modified 用于服務器端的響應,是一個資源最后被修改的時間戳,客戶端(緩存)可以根據
此信息判斷是否需要重新獲取該資源
ETag 服務器端資源版本的標示,客戶端(緩存)可以根據此信息判斷是否需要重新獲取該資源,
需要注意的是,ETag如果通過服務器隨機生成,可能會存在多個主機對同一個資源產生不同ETag的問題
Store類型的資源要支持有條件的PUT請求
1 |
假設有兩個客戶端client#1/#2都向一個Store資源提交PUT請求,服務端是無法清楚的判斷是要 |
Location 在響應header中使用,一般為客戶端感興趣的資源URI,例如在成功創建一個資源后,我們
可以把新的資源URI放在Location中,如果是一個異步創建資源的請求,接口在響應202 (“Accepted”)
的同時可以給予客戶端一個異步狀態查詢的地址
Cache-Control, Expires, Date 通過緩存機制提升接口響應性能,同時根據實際需要也可以禁止
客戶端對接口請求做緩存。對于REST接口來說,如果某些接口實時性要求不高的情況下,我們可以使
用max-age來指定一個小的緩存時間,這樣對客戶端和服務器端雙方都是有利的。一般來說只對GET
方法且返回200的情況下使用緩存,在某些情況下我們也可以對返回3xx或者4xx的情況下做緩存,可
以防范錯誤訪問帶來的負載。
我們可以自定義一些頭信息,作為客戶端和服務器間的通信使用,但不能改變HTTP方法的性質。自
定義頭盡量簡單明了,不要用body中的信息對其作補充說明。
API 地址和版本
在 url 中指定 API 的版本是個很好地做法。如果 API 變化比較大,可以把 API 設計為子域名,
比如https://api.github.com/v3;也可以簡單地把版本放在路徑中,比如https://example.com/api/v1。
另一種做法是,將版本號放在HTTP頭信息中。
限流 rate limit
如果對訪問的次數不加控制,很可能會造成 API 被濫用,甚至被 DDos 攻擊。根據使用者不同的身
份對其進行限流,可以防止這些情況,減少服務器的壓力。
對用戶的請求限流之后,要有方法告訴用戶它的請求使用情況,Github API 使用的三個相關的頭部:
X-RateLimit-Limit: 用戶每個小時允許發送請求的最大值
X-RateLimit-Remaining:當前時間窗口剩下的可用請求數目
X-RateLimit-Rest: 時間窗口重置的時候,到這個時間點可用的請求數量就會變成 X-RateLimit-Limit 的值
對于超過流量的請求,可以返回 429 Too many requests 狀態碼,并附帶錯誤信息。
參考文檔
http://cizixs.com/2016/12/12/restful-api-design-guide
http://wangwei.info/about-rest-api/
http://www.ruanyifeng.com/blog/2011/09/restful.html
http://www.ruanyifeng.com/blog/2014/05/restful_api.html
https://zh.wikipedia.org/wiki/REST
https://developer.github.com/v3
總結
以上是生活随笔為你收集整理的REST介绍以及常用的返回状态码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ubuntu下安装mysql 杂记
- 下一篇: aswing 换肤