1、RESTful發展背景及簡介
網絡應用程序,分爲前端和後端兩個部分。當前的發展趨勢,就是前端設備層出不窮(手機、平板、桌面電腦、其他專用設備......)。因此,必須有一種統一的機制,方便不同的前端設備與後端進行通信。這導致API構架的流行,甚至出現"APIFirst"的設計思想。RESTful API是目前比較成熟的一套互聯網應用程序的API設計理論。
REST(Representational State Transfer)表述性狀態轉換,REST指的是一組架構約束條件和原則。 如果一個架構符合REST的約束條件和原則,我們就稱它爲RESTful架構。REST本身並沒有創造新的技術、組件或服務,而隱藏在RESTful背後的理念就是使用Web的現有特徵和能力, 更好地使用現有Web標準中的一些準則和約束。雖然REST本身受Web技術的影響很深, 但是理論上REST架構風格並不是綁定在HTTP上,只不過目前HTTP是唯一與REST相關的實例。
2、RESTful設計風格
2.1、推薦格式
1)url格式:
http(s)://server.com/api-name/{version}/{domain}/{rest-convention} {version}代表api的版本信息。 {domain}是一個你可以用來定義任何技術的區域(例如:安全-允許指定的用戶可以訪問這個區域。)或者業務上的區域(例如:同樣的功能在同一個前綴之下)。 {rest-convention} 代表這個域(domain)下,約定的rest接口集合。
2)參數格式:
GET採用兩種常見格式:
① URL參數(更推薦),如:
https://www.example.com/v1.1?name=‘lk-abc%’&age=’lt-10’
②路徑參數,如:
https://www.example.com/v1.1/employees/{id}
POST採用兩種常見格式:
①Json格式包裝參數提交
POST https://www.example.com/v1.1 Content-Type: application/json;charset=utf-8 {"title":"test","sub":[1,2,3]}
②form表單參數提交
POST https://www.example.com/v1.1 Content-Type: application/x-www-form-urlencoded;charset=utf-8 title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
3)返回體格式:
{ "status": 200, "message":"用戶查詢返回成功", "document":”https://www.example.com/doc#userinfo", "data": { "className": "com.fiberhome.smartas.pricecloud.User", "id":"1b434wtert564564sdffey32", "name": "lilei", "age": 18, "job": { "className”:"com.fiberhome.smartas.pricecloud.Job", "id": "1b434wtert564564sdffeyey", "name": "微服務架構師" } } }
2.2、協議
考慮到服務的安全性,建議使用https作爲API的通信協議,當然http也是可以的。
2.3、域名
建議將API部署在專有域名下,以此屏蔽消費者對服務提供方的部署細節(可藉助於平臺的反向代理+路由網關),在服務地圖豐富起來之後可以考慮多級域名。
https://api.example.com https://example.org/api/
2.4、版本
考慮到微服務的平滑升級,可以將API的版本號放入URL,也可以將版本號放在HTTP頭信息中,但不如放入URL方便和直觀。Github採用這種做法。
https://api.example.com/v1/
2.5、複數名詞路徑
在RESTful架構中,每個網址代表一種資源(resource),所以網址中不能有動詞,只能有名詞,而且所用的名詞往往與數據庫的表格名對應。一般來說,數據庫中的表都是同種記錄的"集合"(collection),所以API中的名詞也應該使用複數。
https://api.example.com/v1/employees
2.6、http協議類型表達資源操作
HTTP協議裏的8種方法,及其他衍生方法,常用的Get、post可以間接的實現其餘所有的操作,根據框架和瀏覽器的兼容性選擇性使用。
1) GET(SELECT) :從服務器取出資源(一項或多項)。 2) POST(CREATE) :在服務器新建一個資源。 3) PUT(UPDATE) :在服務器更新資源(客戶端提供改變後的完整資源)。 4) PATCH(UPDATE):在服務器更新資源(客戶端提供改變的屬性)。 5) DELETE(DELETE):從服務器刪除資源 6) HEAD:獲取資源的元數據。 7) OPTIONS:獲取信息,關於資源的哪些屬性是客戶端可以改變的。 8) TRACE:回顯服務器收到的請求,主要用於測試或診斷。 9) CONNECT:HTTP/1.1協議中預留給能夠將連接改爲管道方式的代理服務器。 10) MOVE: 請求服務器將指定的頁面移至另一個網絡地址。 11) COPY: 請求服務器將指定的頁面拷貝至另一個網絡地址。 12) LINK: 請求服務器建立鏈接關係。 13) UNLINK: 斷開鏈接關係。 14) WRAPPED: 允許客戶端發送經過封裝的請求。 15) Extension-mothed:在不改動協議的前提下,可增加另外的方法。 例:
GET https://api.example.com/v1/employees/ 獲取所有僱員
2.7、過濾信息
請求信息應該爲集合提供過濾、排序、選擇和分頁等功能
1)Filtering過濾:
使用唯一的查詢參數進行過濾:
GET /cars?color=red 返回紅色的cars
2)Sorting排序:
允許針對多個字段排序
GET /cars?sort=-manufactorer,+model #這是返回根據生產者降序和模型升序排列的car集合
3)Fieldselection
移動端能夠顯示其中一些字段,它們其實不需要一個資源的所有字段,給API消費者一個選擇字段的能力,這會降低網絡流量,提高API可用性。
GET /cars?fields=manufacturer,model,id,color
4)Paging分頁
使用 limit 和offset.實現分頁,缺省limit=20 和offset=0;
GET /cars?offset=10&limit=5
爲了將總數發給客戶端,使用訂製的HTTP頭:X-Total-Count.
鏈接到下一頁或上一頁可以在HTTP頭的link規定,遵循Link規定:
Link: <https://blog.mwaysolutions.com/sample/api/v1/cars?offset=15&limit=5>;rel="next", <https://blog.mwaysolutions.com/sample/api/v1/cars?offset=50&limit=3>;rel="last", <https://blog.mwaysolutions.com/sample/api/v1/cars?offset=0&limit=5>;rel="first", <https://blog.mwaysolutions.com/sample/api/v1/cars?offset=5&limit=5>;rel="prev",
2.8、返回結果爲統一的json格式
一方面,出於平臺標準化的API管理,另一方面,遵循微服務的寬進嚴出設計理念,建議RESTful採用標準的Json格式。
返回結構體:
{ "className": "com.fiberhome.smartas.pricecloud.User", "id":"1b434wtert564564sdffey32", "name": "lilei", "age": 18, "job": { "className":"com.fiberhome.smartas.pricecloud.Job", "id": "1b434wtert564564sdffeyey", "name": "微服務架構師" } }
2.9、返回結果應該包含狀態碼
常見狀態碼,Http1.1協議完整狀態碼定義參考地址:
1) 200 OK [GET]:服務器成功返回用戶請求的數據,該操作是冪等的(Idempotent) 2) 201 CREATED [POST/PUT/PATCH]:用戶新建或修改數據成功 3) 202 Accepted [*]:表示一個請求已經進入後臺排隊(異步任務) 4) 204 NO CONTENT [DELETE]:用戶刪除數據成功 5) 400 INVALID REQUEST [POST/PUT/PATCH]:用戶發出的請求有錯誤,服務器沒有進行新建或修改數據的操作,該操作是冪等的 6) 401 Unauthorized [*]:表示用戶沒有權限(令牌、用戶名、密碼錯誤) 7) 403 Forbidden [*] 表示用戶得到授權(與401錯誤相對),但是訪問是被禁止的 8) 404 NOT FOUND [*]:用戶發出的請求針對的是不存在的記錄,服務器沒有進行操作,該操作是冪等的 9) 406 Not Acceptable [GET]:用戶請求的格式不可得(比如用戶請求JSON格式,但是隻有XML格式) 10) 410Gone [GET]:用戶請求的資源被永久刪除,且不會再得到的 11) 422Unprocesable entity [POST/PUT/PATCH] 當創建一個對象時,發生一個驗證錯誤 12) 500INTERNAL SERVER ERROR [*]:服務器發生錯誤,用戶將無法判斷髮出的請求是否成功
2.10、返回結果中提供幫助鏈接
RESTful API最好做到Hypermedia,即返回結果中提供鏈接,連向其他API方法,使得用戶不查文檔,也知道下一步應該做什麼。注:Github就是這麼做的
返回體結構:
{"link": { "document":" https://www.example.com/docs#zoos", "href":"https://api.example.com/zoos", "title":"List of zoos", "type":"application/vnd.yourformat+json" } }
2.11、API擴展事項
1)RESTful API依託PaaS平臺治理,需要對API進行認證、授權、參數加密等操作,可考慮在HTTP頭部加認證token、調用鏈指令、狀態信息等系列信息。
2)如PPT所言,API分層,會有內部API和外部API之分,兩種API的設計或有不同(甚至是不同協議)。
3)對於API設計的狀態選擇,建議爲無狀態、N次冪等,但後續或存在性能優化問題,http2.0待評測。