在之前,一個網站的完成老是「all in one」,頁面,數據,渲染所有在服務端完成,這樣作的最大的弊端是後期維護,擴展極其痛苦,開發人員必須同時具有先後端知識。因而慢慢的後來興起了先後端分離
的思想: 後端負責數據編造
,而前端則負責數據渲染
,前端靜態頁面調用指定api獲取到有固定格式的數據,再將數據展現出來,這樣呈現給用戶的就是一個」動態「的過程,而關於api這部分的設計則成了一個問題。如何設計出一個便於理解,容易使用的api則成了一個問題。 而所謂的restful
就是用來規範咱們的api的一種約束。前端
rest
是REpresentational State Transfer
三個單詞的縮寫,由Roy Fielding於2000年論文中提出,它表明着分佈式服務的架構風格。而若是想你的api被稱爲restful api,只要遵循其規定的約束便可。數據庫
資源
,經過請求動做(http method)標識要執行的操做,經過返回的狀態碼來表示此次請求的執行結果。資源的描述構成了uri,它通常有如下約束:json
api.example.com/class-manag…後端
api.example.com/device-mana…api
api.example.com/user-manage…瀏覽器
api.example.com/user-manage…緩存
GET
:查詢操做:HTTP GET /devices?startIndex=0&size=20 表示按照查詢條件獲取設備列表服務器
HTTP GET /configurations?startIndex=0&size=20restful
HTTP GET /devices/{id}/configurationssession
HTTP GET /devices/{id}
POST
:新增操做:
HTTP POST /device 表示新增一個設備 PUT
更新操做(表明更新一個實體的全部屬性)
HTTP PUT /devices/{id} 表示更新一個設備(設備惟一id區分) PATCH
部分更新(表明更新一個實體的部分屬性)因爲有的瀏覽器兼容性問題,通常推薦使用put
HTTP PATCH /devices/{id} 表示更新device的部分屬性
DELETE
刪除操做 HTTP DELETE /devices/{id} 表示刪除一個設備,根據id區分
api.example.com/inventory-m… //更易讀
api.example.com/inventory_m… //更容易出錯
在URI中使用小寫字母(特殊狀況除外,例如專有名詞) api.example.org/my-folder/m…
不要使用文件擴展名 文件擴展名看起來很糟糕,不會增長任何優點。刪除它們也會減小URI的長度。沒理由保留它們
api.example.com/device-mana… / 不要使用它 /
api.example.com/device-mana… / *這是正確的URI * /
使用查詢組件過濾URI集合
不少時候,咱們會遇到須要根據某些特定資源屬性對須要排序,過濾或限制的資源集合的要求。爲此,請不要建立新的API - 而是在資源集合API中啓用排序,過濾和分頁功能,並將輸入參數做爲查詢參數傳遞。例如
http://api.example.com/device-management/managed-devices
http://api.example.com/device-management/managed-devices?region=USA
http://api.example.com/device-management/managed-devices?region=USA&brand=XYZ
http://api.example.com/device-management/managed-devices?region=USA&brand=XYZ&sort=installation-date
複製代碼
/
做爲URI路徑中的最後一個字符,正斜槓(/)不會添加語義值,並可能致使混淆。最好徹底放棄它們。
1xx:信息 通訊傳輸協議級信息。
2xx:成功 表示客戶端的請求已成功接受。
3xx:重定向 表示客戶端必須執行一些其餘操做才能完成其請求。
4xx:客戶端錯誤 此類錯誤狀態代碼指向客戶端。
5xx:服務器錯誤 服務器負責這些錯誤狀態代碼。 另外完整的更爲詳細的狀態碼此處不作贅述。通常簡化版本的api會使用200,400,500,其中400表明客戶端調用有誤,將具體業務邏輯錯誤信息放入response body:
{
"error": "username.or.password.error"
}
複製代碼
api版本定義
當咱們須要對現有的api接口升級的時候,由於該api接口已經投入使用,因此新添加的業務可能沒法保證兼容原來的邏輯,這個時候就須要新的接口,而這個接口通常表示對原來的接口的升級(不一樣版本),那版本怎麼定義呢?
使REST API無狀態有一些很是顯着的優勢:
無狀態經過將API部署到多個服務器,有助於將API擴展到數百萬併發用戶。任何服務器均可以處理任何請求,由於沒有與會話相關的依賴。(集羣)
無狀態使得REST API不那麼複雜 - 能夠刪除全部服務器端狀態同步邏輯。(刪除session,清理多餘空間)
無狀態API也很容易緩存。特定軟件能夠經過查看該一個請求來決定是否緩存HTTP請求的結果。從先前的請求中得到的狀態可能會影響這個請求的可緩存性,這並不存在任何不肯定性。它提升了應用程序的性能。
服務器永遠不會忘記每一個客戶端身份」,由於客戶端會在每一個請求中發送全部必要的信息。(攜帶token)
那麼無狀態又要怎麼實現呢?前面咱們已經說了,服務端不該該再保存session會話,這個工做所有交由http請求去標識,而最多見的作法則是使用token。生成token能夠考慮使用jwt,oauth。其中jwt能夠參考個人另外一篇文章:www.jianshu.com/p/6ff0e30fc…
咱們首先介紹rest服務背景,引出rest架構的介紹,最後重點介紹了rest api的約束設計。
關注我,這裏只有乾貨!