對RESTful API的個人看法
什麼是REST?
可以總結為一句話:REST是所有Web應用都應該遵守的架構設計指導原則。
Representational State Transfer,翻譯是”表現層狀態轉化”。
面向資源是REST最明顯的特徵,對於同一個資源的一組不同的操作。資源是伺服器上一個可命名的抽象概念,資源是以名詞為核心來組織的,首先關注的是名詞。REST要求,必須通過統一的介面來對資源執行各種操作。對於每個資源只能執行一組有限的操作。(7個HTTP方法:GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS)
什麼是RESTful API?
符合REST架構設計的API。
1. 什麼是REST
REST全稱是Representational State Transfer,中文意思是表述(編者注:通常譯為表徵)性狀態轉移。 它首次出現在2000年Roy Fielding的博士論文中,Roy Fielding是HTTP規範的主要編寫者之一。 他在論文中提到:"我這篇文章的寫作目的,就是想在符合架構原理的前提下,理解和評估以網路為基礎的應用軟體的架構設計,得到一個功能強、效能好、適宜通訊的架構。REST指的是一組架構約束條件和原則。" 如果一個架構符合REST的約束條件和原則,我們就稱它為RESTful架構。
REST本身並沒有創造新的技術、元件或服務,而隱藏在RESTful背後的理念就是使用Web的現有特徵和能力, 更好地使用現有Web標準中的一些準則和約束。雖然REST本身受Web技術的影響很深, 但是理論上REST架構風格並不是繫結在HTTP上,只不過目前HTTP是唯一與REST相關的例項。 所以我們這裡描述的REST也是通過HTTP實現的REST。
2. 理解RESTful
要理解RESTful架構,需要理解Representational State Transfer這個片語到底是什麼意思,它的每一個詞都有些什麼涵義。
下面我們結合REST原則,圍繞資源展開討論,從資源的定義、獲取、表述、關聯、狀態變遷等角度,列舉一些關鍵概念並加以解釋。
- 資源與URI
- 統一資源介面
- 資源的表述
- 資源的連結
- 狀態的轉移
2. 1 資源與URI
REST全稱是表述性狀態轉移,那究竟指的是什麼的表述? 其實指的就是資源。任何事物,只要有被引用到的必要,它就是一個資源。資源可以是實體(例如手機號碼),也可以只是一個抽象概念(例如價值) 。下面是一些資源的例子:
- 某使用者的手機號碼
- 某使用者的個人資訊
- 最多使用者訂購的GPRS套餐
- 兩個產品之間的依賴關係
- 某使用者可以辦理的優惠套餐
- 某手機號碼的潛在價值
要讓一個資源可以被識別,需要有個唯一標識,在Web中這個唯一標識就是URI(Uniform Resource Identifier)。
URI既可以看成是資源的地址,也可以看成是資源的名稱。如果某些資訊沒有使用URI來表示,那它就不能算是一個資源, 只能算是資源的一些資訊而已。URI的設計應該遵循可定址性原則,具有自描述性,需要在形式上給人以直覺上的關聯。這裡以github網站為例,給出一些還算不錯的URI:
- https://github.com/git
- https://github.com/git/git
- https://github.com/git/git/blob/master/block-sha1/sha1.h
- https://github.com/git/git/commit/e3af72cdafab5993d18fae056f87e1d675913d08
- https://github.com/git/git/pulls
- https://github.com/git/git/pulls?state=closed
- https://github.com/git/git/compare/master…next
下面讓我們來看看URI設計上的一些技巧:
- 使用_或-來讓URI可讀性更好
曾經Web上的URI都是冰冷的數字或者無意義的字串,但現在越來越多的網站使用_或-來分隔一些單詞,讓URI看上去更為人性化。 例如國內比較出名的開源中國社群,它上面的新聞地址就採用這種風格, 如http://www.oschina.net/news/38119/oschina-translate-reward-plan。
- 使用/來表示資源的層級關係
例如上述/git/git/commit/e3af72cdafab5993d18fae056f87e1d675913d08就表示了一個多級的資源, 指的是git使用者的git專案的某次提交記錄,又例如/orders/2012/10可以用來表示2012年10月的訂單記錄。
- 使用?用來過濾資源
很多人只是把?簡單的當做是引數的傳遞,很容易造成URI過於複雜、難以理解。可以把?用於對資源的過濾, 例如/git/git/pulls用來表示git專案的所有推入請求,而/pulls?state=closed用來表示git專案中已經關閉的推入請求, 這種URL通常對應的是一些特定條件的查詢結果或演算法運算結果。
- ,或;可以用來表示同級資源的關係
有時候我們需要表示同級資源的關係時,可以使用,或;來進行分割。例如哪天github可以比較某個檔案在隨意兩次提交記錄之間的差異,或許可以使用/git/git /block-sha1/sha1.h/compare/e3af72cdafab5993d18fae056f87e1d675913d08;bd63e61bdf38e872d5215c07b264dcc16e4febca作為URI。 不過,現在github是使用…來做這個事情的,例如/git/git/compare/master…next。
2. 2 統一資源介面
RESTful架構應該遵循統一介面原則,統一介面包含了一組受限的預定義的操作,不論什麼樣的資源,都是通過使用相同的介面進行資源的訪問。介面應該使用標準的HTTP方法如GET,PUT和POST,並遵循這些方法的語義。
如果按照HTTP方法的語義來暴露資源,那麼介面將會擁有安全性和冪等性的特性,例如GET和HEAD請求都是安全的, 無論請求多少次,都不會改變伺服器狀態。而GET、HEAD、PUT和DELETE請求都是冪等的,無論對資源操作多少次, 結果總是一樣的,後面的請求並不會產生比第一次更多的影響。
下面列出了GET,DELETE,PUT和POST的典型用法:
GET
- 安全且冪等
- 獲取表示
- 變更時獲取表示(快取)
- 200(OK) - 表示已在響應中發出
- 204(無內容) - 資源有空表示
- 301(Moved Permanently) - 資源的URI已被更新
- 303(See Other) - 其他(如,負載均衡)
- 304(not modified)- 資源未更改(快取)
- 400 (bad request)- 指代壞請求(如,引數錯誤)
- 404 (not found)- 資源不存在
- 406 (not acceptable)- 服務端不支援所需表示
- 500 (internal server error)- 通用錯誤響應
- 503 (Service Unavailable)- 服務端當前無法處理請求
POST
- 不安全且不冪等
- 使用服務端管理的(自動產生)的例項號建立資源
- 建立子資源
- 部分更新資源
- 如果沒有被修改,則不過更新資源(樂觀鎖)
- 200(OK)- 如果現有資源已被更改
- 201(created)- 如果新資源被建立
- 202(accepted)- 已接受處理請求但尚未完成(非同步處理)
- 301(Moved Permanently)- 資源的URI被更新
- 303(See Other)- 其他(如,負載均衡)
- 400(bad request)- 指代壞請求
- 404 (not found)- 資源不存在
- 406 (not acceptable)- 服務端不支援所需表示
- 409 (conflict)- 通用衝突
- 412 (Precondition Failed)- 前置條件失敗(如執行條件更新時的衝突)
- 415 (unsupported media type)- 接受到的表示不受支援
- 500 (internal server error)- 通用錯誤響應
- 503 (Service Unavailable)- 服務當前無法處理請求
PUT
- 不安全但冪等
- 用客戶端管理的例項號建立一個資源
- 通過替換的方式更新資源
- 如果未被修改,則更新資源(樂觀鎖)
- 200 (OK)- 如果已存在資源被更改
- 201 (created)- 如果新資源被建立
- 301(Moved Permanently)- 資源的URI已更改
- 303 (See Other)- 其他(如,負載均衡)
- 400 (bad request)- 指代壞請求
- 404 (not found)- 資源不存在
- 406 (not acceptable)- 服務端不支援所需表示
- 409 (conflict)- 通用衝突
- 412 (Precondition Failed)- 前置條件失敗(如執行條件更新時的衝突)
- 415 (unsupported media type)- 接受到的表示不受支援
- 500 (internal server error)- 通用錯誤響應
- 503 (Service Unavailable)- 服務當前無法處理請求
DELETE
- 不安全但冪等
- 刪除資源
- 200 (OK)- 資源已被刪除
- 301 (Moved Permanently)- 資源的URI已更改
- 303 (See Other)- 其他,如負載均衡
- 400 (bad request)- 指代壞請求
- 404 (not found)- 資源不存在
- 409 (conflict)- 通用衝突
- 500 (internal server error)- 通用錯誤響應
- 503 (Service Unavailable)- 服務端當前無法處理請求
下面我們來看一些實踐中常見的問題:
- POST和PUT用於建立資源時有什麼區別?
POST和PUT在建立資源的區別在於,所建立的資源的名稱(URI)是否由客戶端決定。 例如為我的博文增加一個java的分類,生成的路徑就是分類名/categories/java,那麼就可以採用PUT方法。不過很多人直接把POST、GET、PUT、DELETE直接對應上CRUD,例如在一個典型的rails實現的RESTful應用中就是這麼做的。
我認為,這是因為rails預設使用服務端生成的ID作為URI的緣故,而不少人就是通過rails實踐REST的,所以很容易造成這種誤解。
- 客戶端不一定都支援這些HTTP方法吧?
的確有這種情況,特別是一些比較古老的基於瀏覽器的客戶端,只能支援GET和POST兩種方法。
在實踐上,客戶端和服務端都可能需要做一些妥協。例如rails框架就支援通過隱藏引數_method=DELETE來傳遞真實的請求方法, 而像Backbone這樣的客戶端MVC框架則允許傳遞_method傳輸和設定X-HTTP-Method-Override頭來規避這個問題。
- 統一介面是否意味著不能擴充套件帶特殊語義的方法?
統一介面並不阻止你擴充套件方法,只要方法對資源的操作有著具體的、可識別的語義即可,並能夠保持整個介面的統一性。
像WebDAV就對HTTP方法進行了擴充套件,增加了LOCK、UPLOCK等方法。而github的API則支援使用PATCH方法來進行issue的更新,例如:
PATCH /repos/:owner/:repo/issues/:number
不過,需要注意的是,像PATCH這種不是HTTP標準方法的,服務端需要考慮客戶端是否能夠支援的問題。
- 統一資源介面對URI有什麼指導意義?
統一資源介面要求使用標準的HTTP方法對資源進行操作,所以URI只應該來表示資源的名稱,而不應該包括資源的操作。
通俗來說,URI不應該使用動作來描述。例如,下面是一些不符合統一介面要求的URI:
- GET /getUser/1
- POST /createUser
- PUT /updateUser/1
- DELETE /deleteUser/1
如果GET請求增加計數器,這是否違反安全性?
安全性不代表請求不產生副作用,例如像很多API開發平臺,都對請求流量做限制。像github,就會限制沒有認證的請求每小時只能請求60次。
但客戶端不是為了追求副作用而發出這些GET或HEAD請求的,產生副作用是服務端"自作主張"的。
另外,服務端在設計時,也不應該讓副作用太大,因為客戶端認為這些請求是不會產生副作用的。
- 直接忽視快取可取嗎?
即使你按各個動詞的原本意圖來使用它們,你仍可以輕易禁止快取機制。 最簡單的做法就是在你的HTTP響應裡增加這樣一個報頭: Cache-control: no-cache。 但是,同時你也對失去了高效的快取與再驗證的支援(使用Etag等機制)。
對於客戶端來說,在為一個REST式服務實現程式客戶端時,也應該充分利用現有的快取機制,以免每次都重新獲取表示。
- 響應程式碼的處理有必要嗎?
HTTP的響應程式碼可用於應付不同場合,正確使用這些狀態程式碼意味著客戶端與伺服器可以在一個具備較豐富語義的層次上進行溝通。
例如,201("Created")響應程式碼表明已經建立了一個新的資源,其URI在Location響應報頭裡。
假如你不利用HTTP狀態程式碼豐富的應用語義,那麼你將錯失提高重用性、增強互操作性和提升鬆耦合性的機會。
如果這些所謂的RESTful應用必須通過響應實體才能給出錯誤資訊,那麼SOAP就是這樣的了,它就能夠滿足了。
2. 3 資源的表述
上面提到,客戶端通過HTTP方法可以獲取資源,是吧? 不,確切的說,客戶端獲取的只是資源的表述而已。 資源在外界的具體呈現,可以有多種表述(或成為表現、表示)形式,在客戶端和服務端之間傳送的也是資源的表述,而不是資源本身。 例如文字資源可以採用html、xml、json等格式,圖片可以使用PNG或JPG展現出來。
資源的表述包括資料和描述資料的後設資料,例如,HTTP頭"Content-Type" 就是這樣一個後設資料屬性。
那麼客戶端如何知道服務端提供哪種表述形式呢?
答案是可以通過HTTP內容協商,客戶端可以通過Accept頭請求一種特定格式的表述,服務端則通過Content-Type告訴客戶端資源的表述形式。
以github為例,請求某組織資源的json格式的表述形式:
假如github也能夠支援xml格式的表述格式,那麼結果就是這樣的:
下面我們來看一些實踐上常見的設計:
在URI裡邊帶上版本號
有些API在URI裡邊帶上版本號,例如:
- http://api.example.com/1.0/foo
- http://api.example.com/1.2/foo
- http://api.example.com/2.0/foo
如果我們把版本號理解成資源的不同表述形式的話,就應該只是用一個URL,並通過Accept頭部來區分,還是以github為例,它的Accept的完整格式是:application/vnd.github[.version].param[+json]
對於v3版本的話,就是Accept: application/vnd.github.v3。對於上面的例子,同理可以使用使用下面的頭部:
- Accept: vnd.example-com.foo+json; version=1.0
- Accept: vnd.example-com.foo+json; version=1.2
- Accept: vnd.example-com.foo+json; version=2.0
使用URI字尾來區分表述格式
像rails框架,就支援使用/users.xml或/users.json來區分不同的格式。 這樣的方式對於客戶端來說,無疑是更為直觀,但混淆了資源的名稱和資源的表述形式。 我個人認為,還是應該優先使用內容協商來區分表述格式。
如何處理不支援的表述格式
當伺服器不支援所請求的表述格式,那麼應該怎麼辦?若伺服器不支援,它應該返回一個HTTP 406響應,表示拒絕處理該請求。下面以github為例,展示了一個請求XML表述資源的結果:
2. 4 資源的連結
我們知道REST是使用標準的HTTP方法來操作資源的,但僅僅因此就理解成帶CURD的Web資料庫架構就太過於簡單了。
這種反模式忽略了一個核心概念:"超媒體即應用狀態引擎(hypermedia as the engine of application state)"。 超媒體是什麼?
當你瀏覽Web網頁時,從一個連線跳到一個頁面,再從另一個連線跳到另外一個頁面,就是利用了超媒體的概念:把一個個把資源連結起來.
要達到這個目的,就要求在表述格式裡邊加入連結來引導客戶端。在《RESTful Web Services》一書中,作者把這種具有連結的特性成為連通性。下面我們具體來看一些例子。
下面展示的是github獲取某個組織下的專案列表的請求,可以看到在響應頭裡邊增加Link頭告訴客戶端怎麼訪問下一頁和最後一頁的記錄。 而在響應體裡邊,用url來連結專案所有者和專案地址。
又例如下面這個例子,建立訂單後通過連結引導客戶端如何去付款。
上面的例子展示瞭如何使用超媒體來增強資源的連通性。很多人在設計RESTful架構時,使用很多時間來尋找漂亮的URI,而忽略了超媒體。所以,應該多花一些時間來給資源的表述提供連結,而不是專注於"資源的CRUD"。
2. 5 狀態的轉移
有了上面的鋪墊,再討論REST裡邊的狀態轉移就會很容易理解了。
不過,我們先來討論一下REST原則中的無狀態通訊原則。初看一下,好像自相矛盾了,既然無狀態,何來狀態轉移一說?
其實,這裡說的無狀態通訊原則,並不是說客戶端應用不能有狀態,而是指服務端不應該儲存客戶端狀態。
2. 5.1 應用狀態與資源狀態
實際上,狀態應該區分應用狀態和資源狀態,客戶端負責維護應用狀態,而服務端維護資源狀態。
客戶端與服務端的互動必須是無狀態的,並在每一次請求中包含處理該請求所需的一切資訊。
服務端不需要在請求間保留應用狀態,只有在接受到實際請求的時候,服務端才會關注應用狀態。
這種無狀態通訊原則,使得服務端和中介能夠理解獨立的請求和響應。
在多次請求中,同一客戶端也不再需要依賴於同一伺服器,方便實現高可擴充套件和高可用性的服務端。
但有時候我們會做出違反無狀態通訊原則的設計,例如利用Cookie跟蹤某個服務端會話狀態,常見的像J2EE裡邊的JSESSIONID。
這意味著,瀏覽器隨各次請求發出去的Cookie是被用於構建會話狀態的。
當然,如果Cookie儲存的是一些伺服器不依賴於會話狀態即可驗證的資訊(比如認證令牌),這樣的Cookie也是符合REST原則的。
2. 5.2 應用狀態的轉移
狀態轉移到這裡已經很好理解了, "會話"狀態不是作為資源狀態儲存在服務端的,而是被客戶端作為應用狀態進行跟蹤的。客戶端應用狀態在服務端提供的超媒體的指引下發生變遷。服務端通過超媒體告訴客戶端當前狀態有哪些後續狀態可以進入。
這些類似"下一頁"之類的連結起的就是這種推進狀態的作用——指引你如何從當前狀態進入下一個可能的狀態。
RESTful API 設計指南
網路應用程式,分為前端和後端兩個部分。當前的發展趨勢,就是前端裝置層出不窮(手機、平板、桌面電腦、其他專用裝置......)。
因此,必須有一種統一的機制,方便不同的前端裝置與後端進行通訊。這導致API構架的流行,甚至出現"API First"的設計思想。RESTful API是目前比較成熟的一套網際網路應用程式的API設計理論。我以前寫過一篇《理解RESTful架構》,探討如何理解這個概念。
今天,我將介紹RESTful API的設計細節,探討如何設計一套合理、好用的API。我的主要參考了兩篇文章(1,2)。
一、協議
API與使用者的通訊協議,總是使用HTTPs協議。
二、域名
應該儘量將API部署在專用域名之下。
https://api.example.com
如果確定API很簡單,不會有進一步擴充套件,可以考慮放在主域名下。
https://example.org/api/
三、版本(Versioning)
應該將API的版本號放入URL。
https://api.example.com/v1/
另一種做法是,將版本號放在HTTP頭資訊中,但不如放入URL方便和直觀。Github採用這種做法。
四、路徑(Endpoint)
路徑又稱"終點"(endpoint),表示API的具體網址。
在RESTful架構中,每個網址代表一種資源(resource),所以網址中不能有動詞,只能有名詞,而且所用的名詞往往與資料庫的表格名對應。一般來說,資料庫中的表都是同種記錄的"集合"(collection),所以API中的名詞也應該使用複數。
舉例來說,有一個API提供動物園(zoo)的資訊,還包括各種動物和僱員的資訊,則它的路徑應該設計成下面這樣。
- https://api.example.com/v1/zoos
- https://api.example.com/v1/animals
- https://api.example.com/v1/employees
五、HTTP動詞
對於資源的具體操作型別,由HTTP動詞表示。
常用的HTTP動詞有下面五個(括號裡是對應的SQL命令)。
- GET(SELECT):從伺服器取出資源(一項或多項)。
- POST(CREATE):在伺服器新建一個資源。
- PUT(UPDATE):在伺服器更新資源(客戶端提供改變後的完整資源)。
- PATCH(UPDATE):在伺服器更新資源(客戶端提供改變的屬性)。
- DELETE(DELETE):從伺服器刪除資源。
還有兩個不常用的HTTP動詞。
- HEAD:獲取資源的後設資料。
- OPTIONS:獲取資訊,關於資源的哪些屬性是客戶端可以改變的。
下面是一些例子。
- GET /zoos:列出所有動物園
- POST /zoos:新建一個動物園
- GET /zoos/ID:獲取某個指定動物園的資訊
- PUT /zoos/ID:更新某個指定動物園的資訊(提供該動物園的全部資訊)
- PATCH /zoos/ID:更新某個指定動物園的資訊(提供該動物園的部分資訊)
- DELETE /zoos/ID:刪除某個動物園
- GET /zoos/ID/animals:列出某個指定動物園的所有動物
- DELETE /zoos/ID/animals/ID:刪除某個指定動物園的指定動物
六、過濾資訊(Filtering)
如果記錄數量很多,伺服器不可能都將它們返回給使用者。API應該提供引數,過濾返回結果。
下面是一些常見的引數。
- ?limit=10:指定返回記錄的數量
- ?offset=10:指定返回記錄的開始位置。
- ?page=2&per_page=100:指定第幾頁,以及每頁的記錄數。
- ?sortby=name&order=asc:指定返回結果按照哪個屬性排序,以及排序順序。
- ?animal_type_id=1:指定篩選條件
引數的設計允許存在冗餘,即允許API路徑和URL引數偶爾有重複。比如,GET /zoo/ID/animals 與 GET /animals?zoo_id=ID 的含義是相同的。
七、狀態碼(Status Codes)
伺服器向使用者返回的狀態碼和提示資訊,常見的有以下一些(方括號中是該狀態碼對應的HTTP動詞)。
- 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 - [*]:伺服器發生錯誤,使用者將無法判斷髮出的請求是否成功。
狀態碼的完全列表參見這裡。
八、錯誤處理(Error handling)
如果狀態碼是4xx,就應該向使用者返回出錯資訊。一般來說,返回的資訊中將error作為鍵名,出錯資訊作為鍵值即可。
{ error: "Invalid API key" }
九、返回結果
針對不同操作,伺服器向使用者返回的結果應該符合以下規範。
- GET /collection:返回資源物件的列表(陣列)
- GET /collection/resource:返回單個資源物件
- POST /collection:返回新生成的資源物件
- PUT /collection/resource:返回完整的資源物件
- PATCH /collection/resource:返回完整的資源物件
- DELETE /collection/resource:返回一個空文件
十、Hypermedia API
RESTful API最好做到Hypermedia,即返回結果中提供連結,連向其他API方法,使得使用者不查文件,也知道下一步應該做什麼。
比如,當使用者向api.example.com的根目錄發出請求,會得到這樣一個文件。
{"link": { "rel": "collection https://www.example.com/zoos", "href": "https://api.example.com/zoos", "title": "List of zoos", "type": "application/vnd.yourformat+json" }}
上面程式碼表示,文件中有一個link屬性,使用者讀取這個屬性就知道下一步該呼叫什麼API了。rel表示這個API與當前網址的關係(collection關係,並給出該collection的網址),href表示API的路徑,title表示API的標題,type表示返回型別。
Hypermedia API的設計被稱為HATEOAS。Github的API就是這種設計,訪問api.github.com會得到一個所有可用API的網址列表。
{ "current_user_url": "https://api.github.com/user", "authorizations_url": "https://api.github.com/authorizations", // ... }
從上面可以看到,如果想獲取當前使用者的資訊,應該去訪問api.github.com/user,然後就得到了下面結果。
{ "message": "Requires authentication", "documentation_url": "https://developer.github.com/v3" }
上面程式碼表示,伺服器給出了提示資訊,以及文件的網址。
十一、其他
(1)API的身份認證應該使用OAuth 2.0框架。
(2)伺服器返回的資料格式,應該儘量使用JSON,避免使用XML。
總結
符合REST設計標準的API,即RESTful API。REST架構設計,遵循的各項標準和準則,就是HTTP協議的表現,換句話說,HTTP協議就是屬於REST架構的設計模式。比如,無狀態,請求-響應。。。
參考:
理解本身的REST架構風格
http://www.infoq.com/cn/articles/understanding-restful-style/
理解RESTful架構
http://www.ruanyifeng.com/blog/2011/09/restful.html
Restful API設計指南
http://www.ruanyifeng.com/blog/2014/05/restful_api.html
REST與RESTFul API最佳實踐
相關文章
- 我對Red Flag Desktop 5.0的個人看法(轉)
- 對比Restful Api和RpcRESTAPIRPC
- 做過頭個人看法
- RESTful 個人理解REST
- 我對工程師轉市場的一些個人看法工程師
- 網上整理的對於Rest和Restful api的理解RESTAPI
- 理解RESTful APIRESTAPI
- 關於面試的一些個人看法面試
- 關於IT培訓機構的個人看法
- PostgREST是PostgreSQL的RESTful APIRESTSQLAPI
- 關於工廠模式的一點個人看法模式
- RESTful風格APIRESTAPI
- GitHub 釋出了 web editor,聊聊個人看法GithubWeb
- 對於Lumen和Laravel的看法Laravel
- Restful API 的設計規範RESTAPI
- 如何更好的設計 RESTful APIRESTAPI
- 如何更好的設計RESTful APIRESTAPI
- restful api最佳實踐RESTAPI
- restful api設計指南RESTAPI
- RESTful API 最佳實踐RESTAPI
- 理解RESTful Api設計RESTAPI
- RESTful API 設計指南RESTAPI
- RESTful API 編寫指南RESTAPI
- 我對組隊學習的看法
- 我對部落格的理解和看法
- 對圖靈社群改版的小看法圖靈
- 對MVP和MVVM的一點看法MVPMVVM
- 我對軟體測試的看法
- 關於"是否需要有程式碼規範"的個人看法
- Restful API 中的錯誤處理RESTAPI
- 好RESTful API的設計原則RESTAPI
- GitHub 的 Restful HTTP API 設計分解GithubRESTHTTPAPI
- 對 Guice Interceptor 的一點 自己 的看法GUI
- RESTFUL API 安全設計指南RESTAPI
- nodejs實現restful APINodeJSRESTAPI
- RESTful API實踐總結RESTAPI
- RESTful api風格介紹RESTAPI
- 一文搞懂RESTful APIRESTAPI