1. 什麼是REST
REST全稱是Representational State Transfer,中文意思是表述(編者注:一般譯爲表徵)性狀態轉移。 它首次出如今2000年Roy Fielding的博士論文中,Roy Fielding是HTTP規範的主要編寫者之一。 他在論文中提到:"我這篇文章的寫做目的,就是想在符合架構原理的前提下,理解和評估以網絡爲基礎的應用軟件的架構設計,獲得一個功能強、性能好、適宜通訊的架構。REST指的是一組架構約束條件和原則。" 若是一個架構符合REST的約束條件和原則,咱們就稱它爲RESTful架構。html
REST自己並無創造新的技術、組件或服務,而隱藏在RESTful背後的理念就是使用Web的現有特徵和能力, 更好地使用現有Web標準中的一些準則和約束。雖然REST自己受Web技術的影響很深, 可是理論上REST架構風格並非綁定在HTTP上,只不過目前HTTP是惟一與REST相關的實例。 因此咱們這裏描述的REST也是經過HTTP實現的REST。web
什麼是RESTful架構:json
每個URI表明一種資源;
客戶端和服務器之間,傳遞這種資源的某種表現層;
客戶端經過四個HTTP動詞(GET/POST/PUT/DELETE),對服務器端資源進行操做,實現」表現層狀態轉化」。
segmentfault
URI
要讓一個資源能夠被識別,須要有個惟一標識,在Web中這個惟一標識就是URI(Uniform Resource Identifier)。 URI既能夠當作是資源的地址,也能夠當作是資源的名稱。若是某些信息沒有使用URI來表示,那它就不能算是一個資源, 只能算是資源的一些信息而已。URI的設計應該遵循可尋址性原則,具備自描述性,須要在形式上給人以直覺上的關聯。api
HTTP動詞
數組
1. 使用GET、POST、PUT、DELETE這幾種請求模式
請求模式也能夠說是動做、數據傳輸方式,一般咱們在web中的form有GET、POST兩種,而在HTTP中,存在下發這幾種。服務器
GET (選擇):從服務器上獲取一個具體的資源或者一個資源列表。
POST (建立): 在服務器上建立一個新的資源。
PUT(更新):以總體的方式更新服務器上的一個資源。
PATCH (更新):只更新服務器上一個資源的一個屬性。
DELETE(刪除):刪除服務器上的一個資源。restful
1.1 使用名詞而不是動詞
Resource
資源網絡
GET
讀 POST
建立 PUT
修改 DELETE
/cars 返回 cars集合 建立新的資源 批量更新cars 刪除全部cars
/cars/711 返回特定的car 該方法不容許(405) 更新一個指定的資源 擅長指定資源
不要使用:數據結構
/getAllCars
/createNewCar
/deleteAllRedCars
1.2 Get方法和查詢參數不該該涉及狀態改變
使用PUT, POST 和DELETE 方法 而不是 GET 方法來改變狀態,不要使用GET 進行狀態改變:
GET /users/711?activate
GET /users/711/activate
1.3 使用複數名詞
不要混淆名詞單數和複數,爲了保持簡單,只對全部資源使用複數。
/cars 而不是 /car
/users 而不是 /user
/products 而不是 /product
/settings 而部署 /setting
1.4 使用子資源表達關係
若是一個資源與另一個資源有關係,使用子資源:
GET /cars/711/drivers/ 返回 car 711的全部司機
GET /cars/711/drivers/4 返回 car 711的4號司機
2. 爲集合提供過濾 排序 選擇和分頁等功能
好比在數據過多, 須要對數據進行分頁請求的時候, 咱們應該統一 API 請求參數. 常見的有這些.
limit=10 指定返回記錄的數量
offset=10 指定返回記錄的開始位置。
page=2&per_page=100 指定第幾頁,以及每頁的記錄數。
sortby=name&order=asc 指定返回結果按照哪一個屬性排序,以及排序順序。
animal_type_id=1 指定篩選條件
Filtering過濾:
使用惟一的查詢參數進行過濾:
GET /cars?color=red 返回紅色的cars
GET /cars?seats<=2 返回小於兩座位的cars集合
Sorting排序:
容許針對多個字段排序
GET /cars?sort=-manufactorer,+model
這是返回根據生產者降序和模型升序排列的car集合
Field selection
移動端可以顯示其中一些字段,它們其實不須要一個資源的全部字段,給API消費者一個選擇字段的能力,這會下降網絡流量,提升API可用性。
GET /cars?fields=manufacturer,model,id,color
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",
3. 版本化你的API
API的開發直接關係了APP是否能夠正常使用,若是本來運行正常的API,忽然改動,那麼以前使用這個API的APP可能沒法正常運行。APP是不可能強迫用戶主動升級的,所以,經過API版原本解決這個問題。也就是說,API的多個版本是同時運行的,並且都要保證能夠正常使用。
按照RESTful的規範,不一樣的版本也應該用相同的API URL,經過header信息來判斷版本,再調用不一樣版本的程序進行處理。可是這明顯會給開發帶來巨大的成本。使得API版本變得強制性,不要發佈無版本的API,使用簡單數字,避免小數點如2.5.
域名
應該儘可能將API部署在專用域名之下,如:https://api.example.com
也能夠放在主域名下:https://example.org/api/
版本
不一樣的版本,用不一樣的URL來提供服務,在URL中經過v一、v2來區分版本號,好比v2.api.xxx.com/user的方式,或者http://api.domain.com/v2 或者http://www.domain.com/api/v2 。
放入到頭信息的Accept中
制定版本並在版本之間平緩過渡對於設計和維護一套API是個巨大的挑戰。因此,最好在設計之初就使用一些方法來預防可能會遇到的問題。
爲了不API的變更致使用戶使用中產生意外結果或調用失敗,最好強制要求全部訪問都須要指定版本號。請避免提供默認版本號,一旦提供,往後想要修改它會至關困難。
最適合放置版本號的位置URL中,或者是頭信息(HTTP Headers)中在 Accept 段中使用自定義類型(content type)與其餘元數據(metadata)一塊兒提交。
https://api.example.com/v1/
或
Accept: application/vnd.heroku+json; version=3
提供 Request-Id
爲每個請求響應包含一個Request-Id字段,並使用UUID做爲該值。經過在客戶端、服務器或任何支持服務上記錄該值,它能主咱們提供一種機制來跟蹤、診斷和調試請求。
4 .json數據類型
Number:整數或浮點數
String:字符串
Boolean:true 或 false
Array:數組包含在方括號[]中
Object:對象包含在大括號{}中
Null:空類型
因此,傳輸的數據類型不能超過這六種數據類型。之前,咱們曾經試過傳輸Date類型,它會轉爲相似於"2016年1月7日 09時17分42秒 GMT+08:00"這樣的字符串,這在轉換時會產生問題,不一樣的解析庫解析方式可能不一樣,有的可能會轉亂,有的可能直接異常了。要避免出錯,必須作特殊處理,本身手動去作解析。爲了根除這種問題,最好的解決方案是用毫秒數或者字符串表示日期。
使用詳細的錯誤包裝錯誤:
{
"errors": [
{
"userMessage": "Sorry, the requested resource does not exist",
"internalMessage": "No car found in the database",
"code": 34,
"more info": "http://dev.mwaysolutions.com/blog/api/v1/errors/12345"
}
]
}
返回的數據結構
{
code:0,
message: "success",
data: { key1: value1, key2: value2, ... }
}
code: 返回碼,0表示成功,非0表示各類不一樣的錯誤
message: 描述信息,成功時爲"success",錯誤時則是錯誤信息
data: 成功時返回的數據,類型爲對象或數組
data字段只在請求成功時纔會有數據返回的。數據類型限定爲對象或數組,當請求須要的數據爲單個對象時則傳回對象,當請求須要的數據是列表時,則爲某個對象的數組。這裏須要注意的就是,不要將data傳入字符串或數字,即便請求須要的數據只有一個,好比token,那返回的data應該爲:
// 正確 data: { token: abcdedf }
9. 使用Http狀態碼處理錯誤
不一樣錯誤須要定義不一樣的返回碼,屬於客戶端的錯誤和服務端的錯誤也要區分,好比1XX表示客戶端的錯誤,2XX表示服務端的錯誤
若是你的API沒有錯誤處理是很難的,只是返回500和出錯堆棧不必定有用
Http狀態碼提供70個出錯,咱們只要使用10個左右:
200 OK - [GET]:服務器成功返回用戶請求的數據,該操做是冪等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:用戶新建或修改數據成功。
202 Accepted - [*]:表示一個請求已經進入後臺排隊(異步任務)
204 NO CONTENT - [DELETE]:用戶刪除數據成功。
400 INVALID REQUEST - [POST/PUT/PATCH]:用戶發出的請求有錯誤,服務器沒有進行新建或修改數據的操做,該操做是冪等的。
401 Unauthorized - [*]:表示用戶沒有權限(令牌、用戶名、密碼錯誤)。
403 Forbidden - [*] 表示用戶獲得受權(與401錯誤相對),可是訪問是被禁止的。
404 NOT FOUND - [*]:用戶發出的請求針對的是不存在的記錄,服務器沒有進行操做,該操做是冪等的。
406 Not Acceptable - [GET]:用戶請求的格式不可得(好比用戶請求JSON格式,可是隻有XML格式)。
410 Gone -[GET]:用戶請求的資源被永久刪除,且不會再獲得的。
422 Unprocesable entity - [POST/PUT/PATCH] 當建立一個對象時,發生一個驗證錯誤。
500 INTERNAL SERVER ERROR - [*]:服務器發生錯誤,用戶將沒法判斷髮出的請求是否成功。
10.容許覆蓋http方法
一些代理只支持POST 和 GET方法, 爲了使用這些有限方法支持RESTful API,須要一種辦法覆蓋http原來的方法。
使用訂製的HTTP頭 X-HTTP-Method-Override 來覆蓋POST 方法.
參考:
https://segmentfault.com/a/1190000008697972#articleHeader3http://blog.csdn.net/jasonhui512/article/details/53141390http://www.cnblogs.com/kuyuecs/p/5949075.htmlhttp://mclspace.com/2015/11/03/restful-note/--------------------- 做者:曾先森向前進 來源:CSDN 原文:https://blog.csdn.net/zwqjoy/article/details/78788915 版權聲明:本文爲博主原創文章,轉載請附上博文連接!