網(wǎng)絡(luò)技術(shù)分享】【第一彈】華為云VPN服務(wù)----輕松部署跨地域互聯(lián)">【華為云網(wǎng)絡(luò)技術(shù)分享】【第一彈】華為云VPN服務(wù)----輕松部署跨地域互聯(lián)
916
2025-03-31
【引言】
代表性狀態(tài)轉(zhuǎn)移(REST)是一種軟件架構(gòu)風(fēng)格,它定義了一套用于創(chuàng)建Web服務(wù)的規(guī)則。符合REST架構(gòu)風(fēng)格的Web服務(wù)被稱為RESTful Web服務(wù),它提供了互聯(lián)網(wǎng)上計算機系統(tǒng)之間的互操作性。RESTful Web服務(wù)允許請求系統(tǒng)通過使用一組統(tǒng)一的、預(yù)定義的無狀態(tài)操作來訪問和操作Web資源的文本格式數(shù)據(jù)。
在互聯(lián)網(wǎng)上,"網(wǎng)絡(luò)資源?"最初被定義為通過URL來標識的文檔或文件。然而,今天,它們有了一個更為通用和抽象的定義,它包含了在Web上可以被識別、命名、尋址、處理或執(zhí)行的所有事物、實體或操作。在?RESTful Web?服務(wù)中,對資源的?URI?提出的請求,會得到一個以?HTML、XML、JSON?或其他格式的有效格式化的數(shù)據(jù)響應(yīng)。這些響應(yīng)可以確認對資源狀態(tài)進行了一些改變,而且這些響應(yīng)也可以提供指向其他相關(guān)資源的超文本鏈接。
當(dāng)使用HTTP時,最常見的操作(HTTP方法)有GET、HEAD、POST、POST、PUT、PATCH、DELETE、CONNECT、OPTIONS和TRACE。
【歷史】
Roy Fielding在2000年在加州大學(xué)歐文分校的博士論文?"Architecture Styles and the Design of Network-based Software Architectures "中對REST進行了定義,他的定義是基于HTTP 1.0的現(xiàn)有設(shè)計基礎(chǔ)上,與HTTP 1.1的發(fā)展時間平行,發(fā)展了REST的架構(gòu)風(fēng)格。
在回顧REST的發(fā)展歷程時,F(xiàn)ielding說:“
在這個HTTP標準化過程中,我需要為這個Web設(shè)計選擇進行辯護。而在這個過程中,這個話題正迅速成為整個行業(yè)的中心,同時需要分析考慮每個人的建議,這是很難做到的。
我收到了來自500多名開發(fā)人員的意見,其中許多人都是有著幾十年經(jīng)驗的杰出工程師,我必須從最抽象的Web交互概念到HTTP語法的最細微的細節(jié)進行解釋。
在這個過程中,?我把這個模型打磨成了一套標準的規(guī)則、屬性和約束,而這些規(guī)則、屬性和約束現(xiàn)在被稱為REST。”
【架構(gòu)特點】
REST架構(gòu)具有以下屬性:
l??組件交互性能,該性能成為影響用戶感知性能和網(wǎng)絡(luò)效率的主導(dǎo)因素;
l??可擴展性,允許支持大量的組件和組件之間的交互。Roy Fielding將REST對可擴展性的影響描述如下:
REST的客戶端與服務(wù)器的分離簡化了組件的實現(xiàn),降低了連接器語義的復(fù)雜性,提高了性能調(diào)優(yōu)的有效性,增加了純服務(wù)器組件的可擴展性。
分層系統(tǒng)允許在通信的不同點引入中間件如代理、網(wǎng)關(guān)和防火墻等,而又不改變組件之間的接口,從而允許它們協(xié)助通信轉(zhuǎn)換或通過大規(guī)模共享緩存提高性能。
REST通過消息規(guī)則的自描述性來實現(xiàn):請求之間的交互是無狀態(tài)的,標準的方法和媒體類型用來表示語義和交換信息,而響應(yīng)本身是可緩存的。
l??統(tǒng)一接口的簡單化。
l??組件的可修改性,以滿足不斷變化的需求(即使是在應(yīng)用程序運行時)。
l??通過服務(wù)代理實現(xiàn)組件之間的通信可視性。
l??組件的可移植性,通過將程序代碼與數(shù)據(jù)一起移動,實現(xiàn)組件的可移植性。
l??在組件、連接器或數(shù)據(jù)內(nèi)部出現(xiàn)故障時,在系統(tǒng)級別提供抗故障的可靠性。
【架構(gòu)方面的規(guī)則】
一個RESTful系統(tǒng)定義了六個指導(dǎo)性規(guī)則。?這些規(guī)則限制了服務(wù)器處理和響應(yīng)客戶端請求的方式,這樣,通過在這些規(guī)則中運行,系統(tǒng)就可以獲得理想的非功能屬性,如性能、可擴展性、簡單性、可修改性、可視性、可移植性和可靠性等。如果一個系統(tǒng)違反了任何一個要求的規(guī)則,就不能被認為是RESTful系統(tǒng)。
正式的REST規(guī)則如下:
客戶端-服務(wù)器架構(gòu)
客戶端-服務(wù)器原則前后端的分離。將用戶界面的部分與數(shù)據(jù)計算存儲分開,這樣可以提高用戶界面在多個平臺上的可移植性,換句話說,多個界面可以共享一個后端服務(wù)。由于簡化服務(wù)器組件,也就提高了后端服務(wù)的可擴展性。對Web應(yīng)用來說,最重要的意義在于,前后端分離后的組件可以各自獨立的發(fā)展,從而支持互聯(lián)網(wǎng)多個領(lǐng)域的需求。
無狀態(tài)
客戶端與服務(wù)器之間的通信是無狀態(tài)的,也就是說客戶端的上下文狀態(tài)不會存放在服務(wù)器上。
任何客戶端的每個請求都包含了服務(wù)請求所需的所有信息,并且會話的狀態(tài)如驗證Token可在客戶端進行保存。這個會話狀態(tài)可以被服務(wù)器轉(zhuǎn)移到另一個服務(wù),如數(shù)據(jù)庫等,以保持一段時間(幾分鐘到幾天不等)的持久狀態(tài),并允許認證。
當(dāng)客戶端準備好過渡到一個新的狀態(tài)時,需要發(fā)送請求到服務(wù)器進行更新。當(dāng)一個或多個請求未完成時,客戶端被認為是處于過渡狀態(tài)。每一個應(yīng)用狀態(tài)會包含鏈接部分,當(dāng)客戶端選擇啟動新的狀態(tài)時,可在下一次發(fā)起請求時使用。
可緩存性
與互聯(lián)網(wǎng)世界里的網(wǎng)頁訪問一樣一樣,客戶端和中間件可以緩存響應(yīng)回來的數(shù)據(jù)。這些響應(yīng)必須以隱式或顯式的方式將自己定義為可緩存或不可緩存,以防止客戶端在響應(yīng)進一步的請求時提供陳舊或不適當(dāng)?shù)臄?shù)據(jù)。
管理良好的緩存可以部分或完全消除一些客戶端與服務(wù)器之間的交互,進一步提高了可擴展性和性能。
分層系統(tǒng)
客戶端通常無法判斷它是直接連接到終端服務(wù)器,還是中間件。如果在客戶端和服務(wù)器之間放置一個代理或負載均衡器,這不會影響它們之間的通信,同時也不需要更新客戶端或服務(wù)器的代碼。
中間件服務(wù)器可以通過啟用負載均衡和提供共享緩存來提高系統(tǒng)的可擴展性。
同時,可以將安全作為一個層添加到Web服務(wù)之上,然后將業(yè)務(wù)邏輯與安全邏輯明確分開,將安全作為一個獨立的安全層,可以強制執(zhí)行安全策略。
最后,這也意味著一個服務(wù)器可以調(diào)用其他多個服務(wù)器來生成響應(yīng)給客戶端。
按需編碼(可選)
服務(wù)器可以通過傳輸可執(zhí)行代碼來臨時擴展或定制客戶端的功能:例如,編譯后的組件,如Java小程序,或客戶端JavaScript腳本。
統(tǒng)一接口
統(tǒng)一接口規(guī)則是任何RESTful系統(tǒng)設(shè)計的根本,它簡化了整個系統(tǒng)的體系結(jié)構(gòu),使每個部分都能獨立演進。?這種統(tǒng)一接口規(guī)則的四個屬性是:
請求中的資源識別
在請求中可以識別單個資源,例如在RESTful Web服務(wù)中使用URIs來標識當(dāng)前的請求資源。資源本身在概念上與返回給客戶端的數(shù)據(jù)表示方式在概念上是分開的。例如,服務(wù)器可以將其數(shù)據(jù)庫中的數(shù)據(jù)以?HTML、XML?或?JSON?的形式發(fā)送,而這些都不需要服務(wù)器端的內(nèi)部邏輯實現(xiàn)。
對返回的資源數(shù)據(jù)可獨立操作
當(dāng)客戶端獲得一個資源數(shù)據(jù)時,包括附加的任何元數(shù)據(jù),它有足夠的信息來修改或刪除這個資源數(shù)據(jù)。
自述性信息
每個消息都包含足夠的信息來描述如何處理消息。例如,可以通過媒體類型指定要調(diào)用哪個解析器來解析數(shù)據(jù)。
Hypermedia作為應(yīng)用狀態(tài)的引擎(HATEOAS)
在訪問了REST應(yīng)用程序的初始URI后,REST客戶端應(yīng)該能夠使用服務(wù)器提供的鏈接動態(tài)地找到它所需要的所有可用資源。隨著訪問請求的執(zhí)行,服務(wù)器會以文本數(shù)據(jù)的方式響應(yīng),其中有可能包括指向當(dāng)前可用的其他資源的超鏈接。客戶端不需要對應(yīng)用程序的結(jié)構(gòu)或動態(tài)信息進行硬編碼。
在網(wǎng)絡(luò)服務(wù)中的應(yīng)用
遵循REST架構(gòu)約束的Web服務(wù)API稱為RESTful API,這種API的定義有以下幾個方面:
l??一個基本URI,如http://api.example.com/collection/。
l??標準的HTTP方法(如GET、POST、PUT、PATCH和DELETE等)。
l??數(shù)據(jù)元素狀態(tài)轉(zhuǎn)換的媒體類型(例如,Atom、microformats、application/vnd.collection+json等)。當(dāng)前的媒體類型告訴客戶端應(yīng)該用何種媒體類型來處理收到的請求??梢院唵稳鏤RI,也可以像Java applet那樣復(fù)雜。
URI和HTTP方法之間的關(guān)系
下表顯示了HTTP方法在HTTP API中的用途,當(dāng)然也包括RESTful方法:
HTTP方法
對數(shù)據(jù)進行計算的資源,如https://api.example.com/collection或https://api.example.com/collection/item3。
調(diào)用操作的資源,如https://api.example.com/clusters/1234/create-vm
POST
調(diào)用該資源提供的操作。如果請求的結(jié)果是創(chuàng)建一個新的資源,其URI將在響應(yīng)頭中返回。
GET
接收響應(yīng)體中的數(shù)據(jù)。
接收響應(yīng)體中的異步操作的狀態(tài)。
PUT
將數(shù)據(jù)存儲在請求體中,也就是資源的目標狀態(tài)。隨后對該資源的對應(yīng)的GET訪問將返回更新后的數(shù)據(jù)。當(dāng)然,如果有進一步的修改,如通過PATCHed、PUT等操作或者數(shù)據(jù)被DELETEd(刪除后),資源的對應(yīng)的GET訪問也要做出相應(yīng)的變化。
PATCH
使用請求正文中的指示更新資源的某些部分狀態(tài)。
DELETE
刪除該資源的狀態(tài)。該資源的GET訪問會返回HTTP狀態(tài)404,直到新的狀態(tài)被添加,如通過PUT等操作。
取消異步操作。
GET方法是安全的,因為它是只讀的,對資源的訪問不會導(dǎo)致資源的狀態(tài)變化。GET、PUT和DELETE方法多次調(diào)用的結(jié)果與調(diào)用一次對資源的影響是一樣的,當(dāng)然響應(yīng)結(jié)果可能不同,比如已經(jīng)完成刪除操作項目X,無法再次刪除項目X。
討論
與基于SOAP的Web服務(wù)不同,RESTful Web API沒有一個?"官方?"標準。這是因為REST是一種架構(gòu)風(fēng)格,而SOAP是一種協(xié)議。REST本身不是一個標準,但RESTful實現(xiàn)利用了一些標準,如HTTP、URI、JSON和XML等標準。許多開發(fā)者也將他們的API描述為RESTful,盡管這些API實際上并沒有滿足上述所有的架構(gòu)規(guī)則(尤其是統(tǒng)一接口規(guī)則)。
下表顯示了傳統(tǒng)的HTTP方法在RPC API中通常是如何使用的:
HTTP方法
資源集合,如:https://api.example.com/collection
單個資源,如:https://api.example.com/collection/item3
GET
返回資源集合。
返回單一資源。
POST
創(chuàng)建資源集合,并返回創(chuàng)建的集合資源的URI,?或者創(chuàng)建一個資源并返回該資源的URI。
創(chuàng)建指定資源,并返回創(chuàng)建的成員資源的URI。
PUT
更新集合資源,如果不存在,則創(chuàng)建資源集合。
更新資源,如不存在就創(chuàng)建。
PATCH
更新集合資源,如果不存在,則創(chuàng)建資源集合。
更新資源,如不存在就創(chuàng)建。
DELETE
刪除資源集合。
刪除資源。
【小結(jié)】
本文對REST架構(gòu)的歷史,特點,規(guī)則和在網(wǎng)絡(luò)服務(wù)中的應(yīng)用進行了介紹。
【不足之處】
其中有一條值得探討,就是統(tǒng)一接口的規(guī)則。
這個規(guī)則的好處是對資源操作指定統(tǒng)一的接口,使得開發(fā)工作非常的簡潔,邏輯上也能夠降低復(fù)雜度。
它的缺點是增加了客戶端調(diào)用和計算的復(fù)雜度,執(zhí)行效率比較低。比如說在真正的業(yè)務(wù)邏輯中,我們需要一個數(shù)據(jù)模型,這個數(shù)據(jù)模型涉及到多個資源,他們分處在不同的表格當(dāng)中,按照統(tǒng)一接口原則,我們需要對每個資源創(chuàng)建接口,然后分別調(diào)用,最后在客戶端對數(shù)據(jù)進行計算整合。
所以在實際的項目開發(fā)中,要從全棧開發(fā)的角度出發(fā),統(tǒng)籌規(guī)劃。我們無需嚴格的按照REST的這條規(guī)則來做。
還是那句話,規(guī)則是為了把工作做得更好:復(fù)雜度低,執(zhí)行效率高。規(guī)則是為產(chǎn)品服務(wù)的,不是相反。當(dāng)規(guī)則的存在出現(xiàn)違背我們工作初衷的情況時,應(yīng)該摒棄規(guī)則,而不是妥協(xié)于規(guī)則。
【解決方案】
針對上面的不足,一個解決方案是對于接口的設(shè)計應(yīng)該按照業(yè)務(wù)邏輯來定義,接口數(shù)據(jù)定義一個數(shù)據(jù)模型,用于包含所有此業(yè)務(wù)邏輯需要的所有資源數(shù)據(jù),對于接口來講,這個模型的數(shù)據(jù)應(yīng)該一個不多一個不少。
這樣設(shè)計以后,客戶端只需一次調(diào)用即可完成本次業(yè)務(wù)需求,而無需多次調(diào)用API再計算。
正如文中所說,REST沒有一個“官方”?的標準,在我們的具體開發(fā)實施中,應(yīng)根據(jù)自身需求,以REST架構(gòu)風(fēng)格規(guī)則為參考,目標是創(chuàng)建出簡單,輕量而又快速的后端API服務(wù)。
歡迎討論。
web前端 HTTP
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。