REST架構(gòu)詳解
REST架構(gòu)詳解
REST架構(gòu)詳解
1.前言
在「遠古時代」前端后端是融合在一起的,比如之前的PHP,JSP,ASP等等。近年來隨著移動互聯(lián)網(wǎng)的飛速發(fā)展,各種類型的Client端層出不窮,就需要通過一套統(tǒng)一的接口分別為Web,iOS和Android乃至桌面端提供服務。另外對于廣大平臺來說,比如Facebook platform,微博開放平臺,微信、QQ公共平臺等,它們不需要有顯式的前端,只需要一套提供服務的接口,于是REST更是它們最好的選擇。
2.RESTful是什么
越來越多的人開始意識到,網(wǎng)站即軟件,而且是一種新型的軟件。
這種"互聯(lián)網(wǎng)軟件"采用客戶端/服務器模式,建立在分布式體系上,通過互聯(lián)網(wǎng)通信,具有高延時、高并發(fā)等特點。
網(wǎng)站開發(fā),完全可以采用軟件開發(fā)的模式。但是傳統(tǒng)上,軟件和網(wǎng)絡是兩個不同的領(lǐng)域,很少有交集;軟件開發(fā)主要針對單機環(huán)境,網(wǎng)絡則主要研究系統(tǒng)之間的通信。互聯(lián)網(wǎng)的興起,使得這兩個領(lǐng)域開始融合,現(xiàn)在我們必須考慮,如何開發(fā)在互聯(lián)網(wǎng)環(huán)境中使用的軟件。
RESTful架構(gòu),就是目前最流行的一種互聯(lián)網(wǎng)軟件架構(gòu)。它結(jié)構(gòu)清晰、符合標準、易于理解、擴展方便,所以正得到越來越多網(wǎng)站的采用。
需要注意的是,REST是一種設計風格而不是標準,如果一個架構(gòu)符合REST原則,我們就稱它為RESTful架構(gòu)。
2.1、起源
在互聯(lián)網(wǎng)行業(yè),實踐總是走在理論的前面。Web 發(fā)展到了 1995 年,在 CGI、ASP 等技術(shù)出現(xiàn)之后,沿用了多年、主要面向靜態(tài)文檔的 HTTP/1.0 協(xié)議已經(jīng)無法滿足 Web 應用的開發(fā)需求,因此需要設計新版本的 HTTP 協(xié)議。在 HTTP/1.0 協(xié)議專家組之中,有一位年輕人脫穎而出,顯示出了不凡的洞察力,后來他成為了 HTTP/1.1 協(xié)議專家組的負責人。這位年輕人就是 Apache HTTP 服務器的核心開發(fā)者 Roy Fielding,他還是 Apache 軟件基金會的合作創(chuàng)始人。
Roy Fielding 和他的同事們在 HTTP/1.1 協(xié)議的設計工作中,對于 Web 之所以取得巨大成功,在技術(shù)架構(gòu)方面的因素做了一番深入的總結(jié)。Fielding 將這些總結(jié)納入到了一套理論框架之中,然后使用這套理論框架中的指導原則,來指導 HTTP/1.1 協(xié)議的設計方向。HTTP/1.1 協(xié)議的第一個草稿是在 1996 年 1 月發(fā)布的,經(jīng)過了三年多時間的修訂,于 1999 年 6 月成為了 IETF 的正式規(guī)范(包括了 RFC 2616 以及用于對客戶端做身份認證的 RFC 2617)。HTTP/1.1 協(xié)議設計的極為成功,以至于發(fā)布之后整整 10 年時間里,都沒有多少人認為有修訂的必要。用來指導 HTTP/1.1 協(xié)議設計的這套理論框架,最初是以備忘錄的形式在專家組成員之間交流,除了 IETF/W3C 的專家圈子,并沒有在外界廣泛流傳。Fielding 在完成 HTTP/1.1 協(xié)議的設計工作之后,回到了加州大學歐文分校繼續(xù)攻讀自己的博士學位。
第二年(2000 年)在他的博士學位論文 Architectural Styles and the Design of Network-based Software Architectures 中,F(xiàn)ielding 更為系統(tǒng)、嚴謹?shù)仃U述了這套理論框架,并且使用這套理論框架推導出了一種新的架構(gòu)風格,并且為這種架構(gòu)風格取了一個費解難懂名字“REST”,即Representational State Transfer(表現(xiàn)層狀態(tài)轉(zhuǎn)化,一般是這個翻譯,但你聽聽這是人話嗎?)的縮寫.應該是缺少了主語。全稱是 Resource Representational State Transfer:通俗來講就是:資源在網(wǎng)絡中以某種表現(xiàn)形式進行狀態(tài)轉(zhuǎn)移。分解開來:
Resource: 資源,即數(shù)據(jù)
Representional:某種表現(xiàn)形式,比如xml,json.
State Transfer:狀態(tài)變化。通過HTTP動詞實現(xiàn)。
2.2、REST架構(gòu)的標志
根據(jù)理查德森模型,REST架構(gòu)的成熟度有3分等級
-
Level 0 POX(這個就不算REST了)。
- 這類應用只有一個URL上的上帝接口,根據(jù)交換的XML內(nèi)容操作所有的資源,往往導致上帝接口越來越復雜,越來越難維護。
-
Level 1 Resource。
- 這一級別主要解決了上帝接口的問題,使得各種資源有了自己相應URL,雖然仍然是POX的交互方式,但每一個接口都更加緊湊和內(nèi)聚,相應的容易維護起來。
- URL templating帶來的結(jié)果是服務器端和客戶端的緊耦合,任何時候服務器端想改變自身的URL scheme的時候,都要break已經(jīng)存在的客戶端應用。
- URL tunneling帶來的問題包含URL templating,而且放棄了使用HTTP協(xié)議標準帶來的任何好處(level2中詳述)。
- 早期的rails routes就是url templating/tunneling。Rails3開始已經(jīng)更新更加靠近level 2了。
-
Level 2 Http verbs
這一級別的使用http verbs來對各種資源進行CRUD操作,使得應用程序的接口更加統(tǒng)一,語義個更加明確。同時應為遵照http協(xié)議的標準進行交互,很多http提供的好處幾乎可以免費的得到。此時使用多個URI的話,需要讓不同的URI代表不同的資源(注意多個URI可能指向同一個Resource,而一個URI不能指向不同Resource。),同時使用多個HTTP方法操作這些資源,例如使用POST/GET/PUT/DELET分別進行CRUD操作。這時候HTTP頭和有效載荷都包含業(yè)務邏輯,例如HTTP方法對應CRUD操作,HTTP狀態(tài)碼對應操作結(jié)果的狀態(tài)。
-
Cache
- 按照HTTP協(xié)議,GET操作是安全的,冪等(idempotent)的,任意多次對同一資源的GET操作,都不會導致資源的狀態(tài)變化。所以GET的結(jié)果是可以安全的cache 。所有http提供的cache facilities都可以被利用起來,大幅度提高了應用程序的性能。甚至你僅僅只是在response里面加上cache directives就可以免費獲得網(wǎng)絡上各級的緩存服務器,代理服務器,以及用戶客戶端的緩存支持。互聯(lián)網(wǎng)上幾乎所有的應用你都可以粗略統(tǒng)計得到Get VS Non-Get的請求比例約為4:1,如果你能為GET操作加上緩存,將極大的提升你的程序性能。
-
Robust
- 在HTTP常用的幾個動詞里,HRAD,GET,PUT,DELETE是安全的,冪等的。因為對同一資源的任一多次請求,永遠代表同一語義,所以任何時候客戶端發(fā)送出去這些動詞的時候,如果服務器沒有響應,或者返回錯誤代碼,客戶端都可以非常安全的再執(zhí)行一次同一操作而不是擔心重復操作帶來的不同語義及最終結(jié)果。POST,PATCH就不是安全的,因為客戶端向服務器端發(fā)送請求之后,服務器沒有響應或者返回錯誤代碼,客戶端是不能安全的重復操作的,一定只是從新與服務器確認現(xiàn)在的資源狀態(tài)才能決定下一步的操作。
絕大部分的RESTful應用就停在這里了,當然也滿足了大多的需求。
-
-
Level 3 Hypermedia controls
-
RESTful的架構(gòu)本意是“在符合架構(gòu)原理的前提下,理解和評估以網(wǎng)絡為基礎的應用軟件的架構(gòu)設計,得到一個功能強,性能好,適宜通信的架構(gòu)”。
-
目前規(guī)模最大,耦合度最低、最穩(wěn)定的、性能最好的分布式網(wǎng)絡應用是什么?就是WEB本身。 規(guī)模、穩(wěn)定、性能都不用說,為什么耦合度低呢?想想每個人上網(wǎng)的經(jīng)歷,你幾乎不需要什么任何培訓就可以上一個新的網(wǎng)絡購物平臺挑選商品,用信用卡付款,郵到自己家里。把網(wǎng)站的程序想象成一個狀態(tài)機,用戶在一系列的狀態(tài)轉(zhuǎn)換中完成自己的目標,中間的每一步,用用程序都告訴你當前的狀態(tài)和可能的下一步操作,最終引導用戶從挑選商品到付款郵寄到家,到達狀態(tài)機的終點。
這種service discoverability和self-documenting就是Level 3想解決的問題。
在這里面,告訴用戶當前的狀態(tài)以及各種下一步操作的東西,例如鏈接,按鈕等等,就是Hypermedia Controls。Hypermedia Controls 就是這個狀態(tài)機的引擎。
Level 3的REST架構(gòu)就是希望能夠統(tǒng)一這一類的Hypermedia Controls, 賦予他們標準的, 高度可擴展的標準語義及表現(xiàn)形式, 使得甚至無人工干預的機器與機器間的通用交互協(xié)議邊的可能. 比如你可以告訴一個通用的購物客戶端, "給我買個最便宜的xbox", 客戶端自動連上google進行搜索, 自動在前10個購物網(wǎng)站進行搜索, 進行價格排序, 然后自動挑選最便宜的網(wǎng)站, 進行一系列操作最終完成用信用卡付費, 填寫個人收件地址然后郵寄.
這些都依賴于Hypermedia Controls帶來的這種service discoverablility和self-documenting
-
當然另外一種更簡便的總結(jié)式可以這樣理解:
-
REST四個基本原則:
- 使用HTTP動詞:GET、 POST 、PUT 、DELETE;
- 無狀態(tài)連接,服務器端不應保存過多上下文狀態(tài),即每個請求都是獨立的;
- 為每個資源設置URI;
- 通過XML JSON進行數(shù)據(jù)傳遞;
實現(xiàn)上述原則的架構(gòu)即可稱為RESTFul架構(gòu)。
- 互聯(lián)網(wǎng)環(huán)境下,任何應用的架構(gòu)和API可以被快速理解;
- 分布式環(huán)境下,任何請求都可以被發(fā)送到任意服務器;
- 異構(gòu)環(huán)境下,任何資源的訪問和使用方式都統(tǒng)一;
RESTful簡單來說就是:URL定位資源,用HTTP動詞(GET,POST,DELETE,DETC)描述操作。
2.3、超媒體(hypermedia)
根據(jù)Roy的嚴格規(guī)定,超媒體(hypermedia)是REST的先決條件,任何其他東西都不應該自我標榜為REST,這里要要先解釋一個概念:超媒體,wiki上面有這樣一個解釋:
多媒體(Multimedia),在電腦應用系統(tǒng)中,組合兩種或兩種以上媒體的一種人機交互式資訊交流和傳播媒體。使用的媒體包括文字、圖片、照片、聲音(包含音樂、語音旁白、特殊音效)、動畫和影片,以及程序所提供的互動功能。
超媒體(Hypermedia)是多媒體系統(tǒng)中的一個子集,超媒體系統(tǒng)是使用超鏈接(Hyperlink)構(gòu)成的全球資訊系統(tǒng),全球資訊系統(tǒng)是互聯(lián)網(wǎng)上使用TCP/IP協(xié)議和UDP/IP協(xié)議的應用系統(tǒng)。2D的多媒體網(wǎng)頁使用HTML、XML等語言編寫,3d的多媒體網(wǎng)頁使用VRML等語言編寫。目前許多多媒體作品使用光碟發(fā)行,以后將更多地使用網(wǎng)絡發(fā)行。
此種關(guān)鍵的角色還是超鏈接,使用超媒體作為應用引擎狀態(tài),意思是應用引擎狀態(tài)變更,由客戶端訪問不同的超媒體資源驅(qū)動。
如下示例:
GET :https://api.github.com/authorizations
{
"author": "github",
"video": {
"large": "https://api.github.com/Japan/large.avi.png",
"medium": "https://api.github.com/Japan/media.avi.png",
"small": "https://api.github.com/Japan/small.avi.png"
}
}
由于在響應中包含了鏈接地址,因此使用該API的客戶端就能夠自由選擇要下載怎樣的信息。這些鏈接告知了客戶端有哪些選擇,并且它們的地址在哪里。
因此在這里我們無需同時返回三個不同版本小視頻,我們所做的只是告訴客戶端有三種不同清晰度可以選擇,并且告訴客戶端能夠在哪里找到這些avi。
這樣一來,客戶端就能夠根據(jù)不同的場景,做出符合自身需要的選擇。而且,如果客戶端只需要一種高清無碼格式的,那就無需下載全部三種。這樣一來可謂一箭三雕:既減少了網(wǎng)絡負載,又增進了客戶端的靈活性,更增進了API的可探索性。
超媒體的核心概念就是所謂的元素,而這些相互鏈接的資源實際上描述了一個協(xié)議,即引導我們達成某個目標的一系列步驟:
例如訂購一杯咖啡所需要的點單、付款、取咖啡等等。這就是超媒體的本質(zhì):經(jīng)由資源之間的鏈接,我們改變整個應用的狀態(tài),即超媒體轉(zhuǎn)換了,分布式應用的狀態(tài)。需要注意的是,服務器和消費者兩者間,交換的是資源狀態(tài)的表述,而不是應用的狀態(tài),被轉(zhuǎn)移的表述中,包括了反應,應用狀態(tài)的鏈接。
2.4、REST誤解
現(xiàn)在看來,REST在2000年那個時代,確實是超前于時代的。Web開發(fā)者社區(qū)對于HTTP的設計意圖存在著大量的誤解,由此導致了對于HTTP的大量低效率的誤用。這個情況持續(xù)一直到2005年Web 2.0的崛起。那個時候,DCOM、EJB、SOAP/WSDL這些DO風格的架構(gòu)由于難以滿足互聯(lián)網(wǎng)環(huán)境對分布式應用架構(gòu)設計的約束,與Web自身的架構(gòu)風格REST相沖突,很難融入到Web之中。所謂的「Web Services」,其實除了將HTTP作為底層的傳輸協(xié)議外,跟(互聯(lián)網(wǎng)環(huán)境中的)真正的Web沒有什么關(guān)系。
而隨著Ruby on Rails這個著名的Web開發(fā)框架開始大力支持REST開發(fā)之后,一線的Web開發(fā)者才真正接觸到了REST。然而Rails所支持的REST開發(fā)將對資源的操作局限于CRUD(創(chuàng)建、獲取、修改、刪除)的語義(即,將對資源的CRUD操作映射到 GET/POST/PUT/DELETE四個HTTP方法),這其實是收窄了REST的適用范圍。其他編程語言的Web開發(fā)框架(例如Java語言的 Struts、Spring MVC等等)也緊接著模仿了Rails的方式開始支持REST開發(fā),然而這更加導致了一線的Web開發(fā)者誤以為:REST開發(fā)就是 通過GET/POST/PUT/DELETE四個HTTP方法對資源執(zhí)行CRUD操作。甚至還有很多僅僅使用了HTTP,而沒有使用SOAP的Web服 務API,都自稱是REST風格(RESTful)的API。
對于什么才是真正的REST風格的誤解是如此之多,而將REST作為一個便于營銷的 buzzword的掛羊頭賣狗肉者也是如此之多,以至于REST的創(chuàng)造者Fielding終于忍無可忍了。2008年10月Fielding寫了一篇博 客,做出了一個非常明確的斷言:REST APIs must be hypertext-driven!(REST API必須是超文本驅(qū)動的!)超文本驅(qū)動這個理念變成了一個縮寫詞HATEOAS,這個縮寫詞來自于當初Fielding博士論文中的一句話: hypermedia as the engine of application state(將超媒體作為應用狀態(tài)的引擎)。
其實超文本驅(qū)動(Hypertext Driven)的理念才是REST架構(gòu)風格最核心的理念,也是REST風格的架構(gòu)達到松耦合目標的根本原因。
3.REST 架構(gòu)風格的推導過程
3.1 REST 所繼承的架構(gòu)風格約束(圖 1)

在圖 1 中,每一個橢圓形里面的縮寫詞代表了一種架構(gòu)風格,而每一個箭頭邊的單詞代表了一種架構(gòu)約束。
- REST 架構(gòu)風格最重要的架構(gòu)約束有 6 個:
-
客戶-服務器(Client-Server)
通信只能由客戶端單方面發(fā)起,表現(xiàn)為請求--響應模式。
-
無狀態(tài)(Stateless)
通信會話狀態(tài)(Session State)應該全部有客戶端負責維護。
-
緩存(Cache)
響應內(nèi)容可以在通信連接的某處緩存,以改善網(wǎng)絡效率
-
統(tǒng)一接口(Uniform Interface)
通信鏈的組件之間通過統(tǒng)一的接口相互通信,以提高交互的可見性。
-
分層系統(tǒng)(Layered System)
通過限制組件的行為(即,每個組件只能“看到”與其交互的緊鄰層),將結(jié)構(gòu)分解成若干等級。
-
按需代碼(Code-On—Demand,可選)
通過支持下載并執(zhí)行一些代碼(例如:Java Applet,F(xiàn)lash或者JS),對客戶端的功能進行擴展。
-
3.2. 在論文中推導出的 REST 架構(gòu)風格如下圖所示:

3.3 .一個基于 REST 的架構(gòu)的過程視圖
而 HTTP/1.1 協(xié)議作為一種 REST 架構(gòu)風格的架構(gòu)實例,其架構(gòu)如下圖所示:

用戶代理處在三個并行交互(a、b 和 c)的中間。用戶代理的客戶端連接器緩存無法滿足請求,因此它根據(jù)每個資源標識符的屬性和客戶端連接器的配置,將每個請求路由到資源的來源。
請求(a)被發(fā)送到一個本地代理,代理隨后訪問一個通過 DNS 查找發(fā)現(xiàn)的緩存網(wǎng)關(guān),該網(wǎng)關(guān)將這個請求轉(zhuǎn)發(fā)到一個能夠滿足該請求的來源服務器,服務器的內(nèi)部資源由一個封裝過的對象請求代理(object request broker)架構(gòu)來定義。
請求(b)直接發(fā)送到一個來源服務器,它能夠通過自己的緩存來滿足這個請求。
請求(c)被發(fā)送到一個代理,它能夠直接訪問 WAIS(一種與 Web 架構(gòu)分離的信息服務),并將 WAIS 的響應翻譯為一種通用的連接器接口能夠識別的格式。每一個組件只知道與它們自己的客戶端或服務器連接器的交互;
4. 為什么要用RESTful結(jié)構(gòu)呢?
4.1. 從架構(gòu)風格的抽象角度來看,常見的分布式應用架構(gòu)風格有三種:
-
1.分布式對象(Distributed Objects,簡稱DO)
架構(gòu)實例有 CORBA/RMI/EJB/DCOM/.NET Remoting 等等
-
2.遠程過程調(diào)用(Remote Procedure Call,簡稱RPC)
架構(gòu)實例有 SOAP/XML-RPC/Hessian/Flash AMF/DWR 等等
-
3.表現(xiàn)層狀態(tài)轉(zhuǎn)移(Representational State Transfer,簡稱REST)
架構(gòu)實例有HTTP/1.1、WebDav
DO 和 RPC 這兩種架構(gòu)風格在企業(yè)應用中非常普遍,而 REST 則是 Web 應用的架構(gòu)風格,它們之間有非常大的差別。
4.2. REST和DO的差別在于:
-
REST支持抽象(即建模)的工具是資源。DO支持抽象的工具是對象。在不同的編程語言中,對象的定義有很大的差別,所以DO風格的架構(gòu)通常都是與某種編程語言綁定的。跨語言交互即使能實現(xiàn),實現(xiàn)是來也是會很復雜。而REST中的資源,則完全中立與開發(fā)平臺和編程語言,可以使用任何編程語言來實現(xiàn)。
-
DO中沒有統(tǒng)一接口的概念。不同API,接口風格可以完全不同。DO也不支持操作語義對于中間件的可見性。
-
DO中沒有使用超文本,響應的內(nèi)容只包含對象本身。REST使用了超媒體,可以實現(xiàn)更大顆粒度的交互,交互的效率比DO高。
-
REST支持數(shù)據(jù)流和管道,DO不支持數(shù)據(jù)流和管道。
-
DO風格通常會來來客戶端和服務端的緊耦合。在三種架構(gòu)風格之中,DO風格的耦合度是最大的,而REST的風格耦合度是最小的。REST松偶合的來源來自統(tǒng)一接口 + 超媒體驅(qū)動。
4.3. REST與RPC的差別在于:
-
REST支持抽象的工具是資源,RPC支持抽象工具是過程。REST風格架構(gòu)建模是以名詞為核心的,RPC風格的架構(gòu)建模是以動詞為核心的。簡單類比一下,REST是面向?qū)ο缶幊蹋琑PC則是面向過程編程。
-
RPC中沒有統(tǒng)一的接口概念。不同的API,接口設計風格可以完全不同,RPC也不支持語義對于中間件的可見性。
-
RPC沒有使用超媒體,響應的內(nèi)容中只包含消息本身。REST使用了超媒體,可以實現(xiàn)更大顆粒度的交互效率也更高。
-
REST支持數(shù)據(jù)流和管道,RPC不支持數(shù)據(jù)流和管道
-
因為使用了平臺中立的消息。RPC風格耦合度比DO風格小一些,但是RPC風格也常常會帶來客戶端和服務器的緊耦合。支持統(tǒng)一接口+超媒體驅(qū)動的風格,可以達到最小的耦合度
4.4. REST 架構(gòu)風格優(yōu)越之處:
比較了三種架構(gòu)風格之間的差別之后,從面向?qū)嵱玫慕嵌葋砜矗琑EST 架構(gòu)風格可以為 Web 開發(fā)者帶來三方面的利益:- 簡單性
采用REST架構(gòu)風格,對于開發(fā)、測試、運維人員來說都會更簡單。可以充分利用大量HTTP服務端和客戶端開發(fā)庫、Web功能測試/性能測試工具、HTTP緩存、HTTP代理服務器、防火墻。這些開發(fā)庫和基礎設施早已成為日常用品,不需要什么高科技(例如神奇昂貴的應用服務器、中間件)就能解決大多數(shù)可伸縮性方面的問題。
- 可伸縮性
充分利用好通訊鏈各個位置的HTTP緩存組件,可以帶來更好的伸縮性。其實很多時候,在Web前端做性能優(yōu)化,產(chǎn)生的效果不亞于僅僅在服務器端做性能優(yōu)化,但是HTTP協(xié)議層面的緩存常常被一些看似很牛逼的人給忽略掉了。
- 松耦合
統(tǒng)一接口 + 超媒體引擎驅(qū)動,帶來了最大限度的松耦合。允許服務器和客戶端在很大范圍內(nèi),相對獨立的運行。對于設計面向企業(yè)內(nèi)網(wǎng)的API來說,松耦合并不是一個很重要的設計關(guān)注點。但是對于設計面向互聯(lián)網(wǎng)的API來說,松耦合成了一個必選項,不僅僅在設計時應該關(guān)注,而且應該昂在最優(yōu)的位子。
下面這段話出自知乎覃超,是一個淺顯易懂的總結(jié):
大家都知道"古代"網(wǎng)頁都是前端后端融在一起的,比如之前的PHP,JSP等。在之前的桌面時代問題不大,但是近年來移動互聯(lián)網(wǎng)的發(fā)展,各種類型的Client層出不窮,RESTful可以通過一套統(tǒng)一的接口為 Web,iOS和Android提供服務。另外對于廣大平臺來說,比如Facebook platform,微博開放平臺,微信公共平臺等,它們不需要有顯式的前端,只需要一套提供服務的接口,于是RESTful更是它們最好的選擇。在RESTful架構(gòu)下:

5. RESTful如何設計
-
1、協(xié)議
- api與用戶的通訊協(xié)議,HTTP/HTTPS。
-
2、域名
-
應盡量將API部署在專用域名之下。
https://api.example.com -
如果確定API很簡單,不會有修改和進一步的擴展,可以考慮放在主域名下。
https://example.com/api/...
-
-
3、版本號
-
版本號放入ULR或者HTTP頭的信息中
https://api.example.com/v1/...
-
-
4、路徑
在RESTful的架構(gòu)中,每個網(wǎng)址代表著一種資源(resource),所以一個好的設計中,網(wǎng)址中不要有動詞,只能用名詞。其實「資源」表示一種實體,所以應該是名詞,動詞應該放在HTTP協(xié)議中。而與此同時URI也有可能破壞HTTP GET的安全性和幕等性,比如某個客戶端在
http://example.com/updateOrder?id=1234&coffee=latte上執(zhí)行GET(而不是POST),就能創(chuàng)建一筆新的咖啡訂單(一個資源),按理來說GET請求不能改變服務的任何狀態(tài)。而且所用名詞往往與數(shù)據(jù)庫中的表格對應。一般來說,數(shù)據(jù)庫中的表都是同種記錄的集合“集合”。
例如:API提供動物園(zoo)的信息,可以這樣設計;https://api.example.com/v1/zoos https://api.example.com/v1/animals https://api.example.com/v1/dogs -
5、HTTP動詞
- GET :用來獲取資源,
- POST :用來新建資源(也可以用于更新資源),
- PUT :用來更新資源,
- DELETE :用來刪除資源。
- PATCH(UPDATE):在服務器更新資源(客戶端提供改變的屬性)。
- HEAD:獲取資源的元數(shù)據(jù)。
- PTIONS:獲取信息,關(guān)于資源的哪些屬性是客戶端可以改變的。
-
6、過濾信息
如果記錄數(shù)量很多,服務器不可能都將他們返回給用戶。API提供參數(shù)返回過濾后的數(shù)據(jù):
* ?limit=10:指定返回記錄的數(shù)量 * ?offset=10:指定返回記錄開始的位置 * ?page-2&per_page=100:指定第幾頁以及每頁的返回數(shù)量 * ?sortby=name&order=asc:指定返回結(jié)果按照哪個屬性排序,以及排序順序 * ?animal_type_id=1:指定篩選條件參數(shù)的設計允許存在冗余,即允許API路徑和URL參數(shù)偶爾有重復。比如,GET /zoo/ID/animals 與 GET /animals?zoo_id=ID 的含義是相同的。
-
7、狀態(tài)碼
服務器向用戶返回的狀態(tài)碼和提示信息,常見的有以下一些(方括號中是該狀態(tài)碼對應的HTTP動詞),查看全部狀態(tài)碼定義點擊這里。
* 200 OK-[GET]:服務器成功返回請求數(shù)據(jù),該操作是冪等的。
* 201 create -[POST/PUT/PATCH]:用戶新建或者修改數(shù)據(jù)
* 202 Accept - [*]標識一個請求進入后臺排隊(異步任務)
* 204 no content - [DELETE]:用戶刪除數(shù)據(jù)成功
* 400 invalid requests- [POST/PUT/PATCH]:用戶發(fā)出的請求錯誤,服務器沒有進行新建或者修改的操作,該操作是冪等的。
* 401 Unauthorized- [*]:標識沒有權(quán)限(令牌,用戶名,密碼錯誤)。
* 403 Forbidden - [*]: 標識用戶得到授權(quán)(與401錯誤相對),但是訪問是被禁止的。
* 404 not found - [*]: y用戶發(fā)出的請求針對的是不是存在的記錄,服務器沒進行操作,這個操作是冪等的。
* 406 Not Acceptable - [GET]:用戶請求格式不可得:(比如用戶請求的是json格式,但是只要xml格式)
* 410 Gone - [GET]:用戶請求資源被永久刪除,且不會再得到。
* 422 Unprocesable entity - [POST/PUT/PATCH]當創(chuàng)建一個對象時候,發(fā)生一個驗證錯誤。
* 500 internal server error - [*] :服務器發(fā)生錯誤,用戶將無法判斷發(fā)出的請求是否成功。
另外附上GitHub的API設計,更具參考價值。
6. 各端的具體實現(xiàn)
如上圖說是,service統(tǒng)一提供了一套RESTful API, web+android+ios作為同級調(diào)用API,現(xiàn)在都有一些比較成熟的框架來幫助開發(fā)者。
1. Server
- 推薦: Spring MVC 或者 Jersey 或者 Play Framework
- 教程:Getting Started · Building a RESTful Web Service
2. Android
- 推薦: RetroFit ( Retrofit ) 或者 Volley ( mcxiaoke/android-volley
- 教程:
- Retrofit ??? Getting Started and Create an Android Client
- 快速Android開發(fā)系列網(wǎng)絡篇之Retrofit
3. iOS
- 推薦:RestKit ( RestKit/RestKit · GitHub )
- 教程:Developing RESTful iOS Apps with RestKit
4. Web
- 可以用重量級的AngularJS,也可以用輕量級 Backbone + jQuery 等。
7. Django REST Framework使用
Django REST Framework應用會在下一遍文章中做詳細分析。
參考資料鏈接:
REST APIs must be hypertext-driven
架構(gòu)風格與基于網(wǎng)絡的軟件架構(gòu)設計(Roy Fielding 博士論文中文版)
原文鏈接:http://www.rzrgm.cn/hanjiangxuedudiao/articles/10898976.html

浙公網(wǎng)安備 33010602011771號