不是標準,是設計風格
REST(英文:Representational State Transfer,簡稱REST),通常應用在web應用程序中,提供一套滿足特定的約束和原則的接口,用于客戶端和服務器交互。REST并沒有一個明確的標準,而更像是一種設計的風格。
來源于一篇論文
Roy Felding 在他論文 network based software architectures 中首次介紹了這些原則。
文章最后是論文下載鏈接(中文版)。80多頁,概念很多,看起來有點無趣。哈哈。
意義深遠
就像REST的作者所說的那樣:
"本文研究計算機科學兩大前沿----軟件和網絡----的交叉點。長期以來,軟件研究主要關注軟件設計的分類、設計方法的演化,很少客觀地評估不同的設計選擇對系統行為的影響。而相反地,網絡研究主要關注系統之間通信行為的細節、如何改進特定通信機制的表現,常常忽視了一個事實,那就是改變應用程序的互動風格比改變互動協議,對整體表現有更大的影響。我這篇文章的寫作目的,就是想在符合架構原理的前提下,理解和評估以網絡為基礎的應用軟件的架構設計,得到一個功能強、性能好、適宜通信的架構。"
基于HTTP
因為大部分用于web應用,底層通訊肯定還是http協議。比如GET,POST那些。這些也是客戶端唯一可以訪問服務端的方式。
URI
HTTP協議中有個很重要的概念:URI(注意不是URL,二者區別請自行搜索學習)
URI,是uniform resource identifier,統一資源標識符,用來唯一的標識一個資源。在RESTful架構中,每個網址代表一種資源(resource)。
網上的一些例子,
ftp://ftp.is.co.za/rfc/rfc1808.txt (also a URL because of the protocol)
http://www.ietf.org/rfc/rfc2396.txt (also a URL because of the protocol)
ldap://[2001:db8::7]/c=GB?objectClass?one (also a URL because of the protocol)
mailto:John.Doe@example.com (also a URL because of the protocol)
news:comp.infosystems.www.servers.unix (also a URL because of the protocol)
tel:+1-816-555-1212
telnet://192.0.2.16:80/ (also a URL because of the protocol)
urn:oasis:names:specification:docbook:dtd:xml:4.1.2
從上面這個例子也可以看出,大部分REST API都是在某個域名之下,這也是實現REST API一個常用的方式。
知乎上的一個例子
比如在JDK中sun公司提供的簡易HttpServer實現中
public void handle(final HttpExchange exchange)throws Exception
方法中,根據exchange對象可以拿到訪問Http請求的URI對象,
ps:
http://127.0.0.1:8080/cmd_helloworld/?name=guowuxin
此時URI uri = exchange.getRequestURI();
通過uri可以拿到連接的各部分內容:
uri.getPath() --------------------> /cmd_helloworld 注意有斜杠
uri.getQuery()----------------------> name=guowuxin
作者:郭無心
鏈接:https://www.zhihu.com/question/21950864/answer/66779836
來源:知乎
著作權歸作者所有,轉載請聯系作者獲得授權。
應用實例
微博 API Error code
論文里對狀態碼有描述:
同樣地,HTTP需要一個通用的規則來解釋新的響應狀態碼,這樣新的響應能夠進行部 署而不會嚴重損害老的客戶端。因此我們擴大了這個規則,規定每個狀態碼屬于一個類別, 通過三位十進制數的第一位數字來表示:100-199表示消息中包含一個臨時的信息響應, 200-299表示請求成功,300-399表示請求需要被重定向到另一個資源,400-499表示客戶 端發生了一個不應該重復的錯誤,500-599表示服務器端遇到了一個錯誤,但是客戶端稍后 可以得到一個更好的響應(或者通過某個其他服務器)。如果接收者不理解一個消息中的狀 態碼的特定語義,那么它們必須將該狀態碼按照與同一類別中狀態碼為x00時相同的方式來 處理。就像是方法名稱的規則一樣,這個可擴展性的規則在當前的架構上添加了一個需求, 這樣架構就能夠預見到未來的改變。改變因此能夠被部署在一個現有架構之上,而無須害怕 出現不利的組件反應(adverse component reactions)。
Github API v3
比如我想獲取一個github上的項目的詳細信息,通過API可以拿到。
比如獲取用戶的基本信息,示例如下:
# GET /users/defunkt
curl https://api.github.com/users/defunkt
{
"login": "defunkt",
"id": 2,
"url": "https://api.github.com/users/defunkt",
"html_url": "https://github.com/defunkt",
...
}
另外有一點,Github API把版本號放在了URL的路徑中,這個在很多參考資料中都不建議。一個很重要的原因是這樣的設計,版本更新都會導致URL更新。不過這樣設計的好處是方便直觀,也有人推崇。
盡量使用JSON,避免使用XML
如果你做的項目多,會發現REST+JSON基本是個標準組合了。之所以沒有用XML我覺得是JSON相對于XML更加簡單,易讀。作為開發者,我個人的經驗是如果API響應的數據是JSON,我更容易發現里面的錯誤。
RESTful架構有一些典型的設計誤區
最常見的一種設計錯誤,就是URI包含動詞。因為"資源"表示一種實體,所以應該是名詞,URI不應該有動詞,動詞應該放在HTTP協議中。舉例來說,某個URI是/posts/show/1,其中show是動詞,這個URI就設計錯了,正確的寫法應該是/posts/1,然后用GET方法表示show。
如果某些動作是HTTP動詞表示不了的,你就應該把動作做成一種資源。比如網上匯款,從賬戶1向賬戶2匯款500元,錯誤的URI是:
POST /accounts/1/transfer/500/to/2
正確的寫法是把動詞transfer改成名詞transaction,資源不能是動詞,但是可以是一種服務:
POST /transaction HTTP/1.1
Host: 127.0.0.1
from=1&to=2&amount=500.00
另一個設計誤區,就是在URI中加入版本號:
http://www.example.com/app/1.0/foo
http://www.example.com/app/1.1/foo
http://www.example.com/app/2.0/foo
因為不同的版本,可以理解成同一種資源的不同表現形式,所以應該采用同一個URI。版本號可以在HTTP請求頭信息的Accept字段中進行區分(參見Versioning REST Services):
Accept: vnd.example-com.foo+json; version=1.0
Accept: vnd.example-com.foo+json; version=1.1
Accept: vnd.example-com.foo+json; version=2.0
一些好玩有用的資料
搜索API
APIs.io - the API search engine
ProgrammableWeb
Nytimes,使用這個API,開發者可以調用到幾百萬份結構化過的數據,從1981 年至今,紐約時報報道的事件,暢銷書,甚至房地產等等
Nytimes
參考