摘要:通過增刪查改,引起資源狀態(tài)的改變,稱為狀態(tài)轉(zhuǎn)移。用于獲取資源的元信息。方法與方法類似,都可以查詢資源的元信息放在的,但不會返回資源的表述。表示請求有問題,如參數(shù)錯誤等。表示當(dāng)前請求的某前置條件不符合。網(wǎng)關(guān)錯誤,從上游服務(wù)器收到無效響應(yīng)。
歡迎大家前往騰訊云+社區(qū),獲取更多騰訊海量技術(shù)實踐干貨哦~
本文由sammyshen 發(fā)表于云+社區(qū)專欄
最近幾年REST API越來越流行,特別是隨著微服務(wù)的概念被廣泛接受和應(yīng)用,很多Web Service都使用了REST API。
REST是HTTP規(guī)范主要編寫者之一的Roy Fielding提出的,全稱是Representational State Transfer,中文可以翻譯為表述性狀態(tài)轉(zhuǎn)移。它不是一種架構(gòu),而是一種架構(gòu)風(fēng)格。REST提出了一組架構(gòu)約束條件和原則,任何滿足REST約束條件和原則的架構(gòu),都稱為RESTful架構(gòu)。
REST雖然流行,但是從業(yè)界應(yīng)用的效果看,良莠不齊。很多系統(tǒng)只是號稱是REST API,實際上并沒有滿足REST的架構(gòu)約束條件。這些系統(tǒng)按照自己的理解,采用了類似REST API的部分形式(如用GET/POST/PUT/DELETE進(jìn)行CURD),但更多的是隨意設(shè)計,搞出了REST-RPC式,甚至是RPC式的API。這樣的API,不僅沒體現(xiàn)出REST API的優(yōu)勢,反而搞成“四不像”,增加了開發(fā)維護(hù)成本。
如何理解REST要規(guī)范使用RESTful架構(gòu),首先要理解什么是REST。我們可以通過分別理解“表述”“狀態(tài)轉(zhuǎn)移”來理解REST。
1) 表述表述指的是資源的表示。RESTful架構(gòu)是基于資源的架構(gòu)(ROA, Resource-Oriented Architecture),在ROA中,處理的對象都是資源。任何需要被引用的對象,都是資源。資源表現(xiàn)為某個具體的URI。
所謂表述,指的是資源的某種形式的表示,這個表示不一定是所有信息,可以只是關(guān)注的部分信息。并且,同一個資源,可以有多個表述。例如,對于一個景點,可以用jpeg照片來表示,也可以用包含位置、介紹等信息的json或xml格式來分別表示。
在REST中,客戶端與服務(wù)器之間的通信,傳輸?shù)亩际琴Y源的表述。
2) 狀態(tài)轉(zhuǎn)移狀態(tài)其實應(yīng)該分為應(yīng)用狀態(tài)和資源狀態(tài)。
應(yīng)用狀態(tài)由客戶端保存維護(hù),例如會話狀態(tài)等。客戶端通過REST API返回的表述,以及表述中的URI,進(jìn)行客戶端應(yīng)用狀態(tài)的轉(zhuǎn)移。
但REST更強(qiáng)調(diào)的是資源狀態(tài)。資源狀態(tài)存儲在服務(wù)器端,客戶端通過REST API,指定請求方法、資源路徑和資源表述(可以包含應(yīng)用狀態(tài)),對資源的狀態(tài)進(jìn)行增刪查改。通過增刪查改,引起資源狀態(tài)的改變,稱為狀態(tài)轉(zhuǎn)移。
3) 結(jié)論結(jié)合上面兩點,客戶端通過REST API對服務(wù)器端的資源進(jìn)行增刪查改,引起資源的狀態(tài)轉(zhuǎn)移。而這種轉(zhuǎn)移是體現(xiàn)在表述上的,所以稱為表述性狀態(tài)轉(zhuǎn)移。
怎樣才算是符合REST架構(gòu)風(fēng)格Roy Fielding在他的論文里通過對一個空架構(gòu)不斷追加約束條件,從而推導(dǎo)出了REST架構(gòu)風(fēng)格。因此,要想符合REST架構(gòu)風(fēng)格,則需要滿足對應(yīng)的約束條件。
image.png
對推導(dǎo)過程感興趣的朋友可以參考Roy Fielding的論文。
REST的約束條件有:
統(tǒng)一接口
無狀態(tài)
緩存
客戶端-服務(wù)器
分層系統(tǒng)
按需代碼(可選)
其中,統(tǒng)一接口是最直觀、也是應(yīng)用中偏差最大的地方,下面會重點講解。其余各約束條件則簡單講解。
1. 統(tǒng)一接口統(tǒng)一接口其實體現(xiàn)在多個方面:
資源URI
請求參數(shù)
請求方法
返回碼
返回內(nèi)容
……
1) 資源URIRESTful架構(gòu)是基于資源的架構(gòu),所操作的一切對象都是資源。因此,需要明確地定位一個資源,而URI技術(shù)正好滿足這個需求,所以REST中通過URI來定位資源。
資源是一個對象,所以URI中一般只能包含名詞(一般是復(fù)數(shù)),不應(yīng)該包含動詞。當(dāng)需要定位具體的資源時,URI中一般包含資源的唯一ID。例如:
// 滿足REST架構(gòu)風(fēng)格的URI http://www.example.com/books // 所有書籍的資源集合 http://www.example.com/books/123 // ID為123的書籍資源 // 不滿足REST架構(gòu)風(fēng)格的URI http://www.example.com/books/query http://www.example.com/buy2) 請求參數(shù)
因為REST需要通過URI來唯一定位某個(或某種)資源,所以查詢資源時,各種資源ID一般是放在URI里面,而不是放在請求參數(shù)里面。請求參數(shù)中一般放過濾條件分頁信息等字段。例如:
// 滿足REST架構(gòu)風(fēng)格的URI http://www.example.com/books/123 // ID為123的書籍資源 http://www.example.com/Fielding/books?page=1&per_page=10 // 作者為Fielding的前10本書籍資源集合 // 不滿足REST架構(gòu)風(fēng)格的URI http://www.example.com/books?id=123 http://www.example.com/books?author=Fielding3) 請求方法
REST約定用GET/POST/PUT/DELETE等請求方法來進(jìn)行CURD操作。但是否使用了GET/POST/PUT/DELETE,并不能作為評判一個系統(tǒng)是否符合REST架構(gòu)風(fēng)格的標(biāo)準(zhǔn)。例如,有些系統(tǒng)所有接口都使用GET和POST方法,如果該系統(tǒng)只提供查詢和創(chuàng)建操作,那么可能是符合REST架構(gòu)風(fēng)格的;但如果該系統(tǒng)還提供修改、刪除操作,則該系統(tǒng)不符合REST架構(gòu)風(fēng)格。
有些人認(rèn)為GET/POST/PUT/DELETE跟CURD是一對一的關(guān)系,其實不是。
具體的說,各請求方法如下:
GET:用于查詢資源。
POST:用于創(chuàng)建資源。POST方法創(chuàng)建資源的URI由服務(wù)器決定,如:POST http://www.example.com/Fieldi...,則是在ID為123的book資源下創(chuàng)建一個某類別資源,如書的評論等,評論的URI也會包含一個服務(wù)器生成的ID。
PUT:用于創(chuàng)建或修改資源。PUT方法創(chuàng)建資源的URI由客戶端決定,如:PUT http://www.example.com/Fieldi...,當(dāng)ID為123的book資源存在時,將進(jìn)行修改操作;否則進(jìn)行創(chuàng)建操作。
DELETE:用于刪除資源。
另外,還有其他較少用的請求方法,需要注意的是可能部分瀏覽器不支持。
HEAD:用于獲取資源的元信息。HEAD方法與GET方法類似,都可以查詢資源的元信息(放在HTTP Response的Header),但不會返回資源的表述。例如用于判斷資源是否存在。
PATCH:用于修改資源。與PUT方法不同的是,PATCH方法只傳輸改動的部分資源表述,而PUT方法需要傳輸完整的資源表述。
4) 返回碼REST使用HTTP返回碼來表示請求的結(jié)果。如果使用規(guī)范的REST API,那么根據(jù)HTTP返回碼就能確定很多信息。常見的HTTP返回碼如下:
200(OK):表示請求成功。
201(Created):表示資源創(chuàng)建成功。
204(No content):表示資源為空。
301(Moved Permanently):表示資源的URI已永久性更改,需要在響應(yīng)內(nèi)容中獲取新的URI。
302(Moved Temporarily):表示資源的URI已臨時性更改,需要在響應(yīng)內(nèi)容中獲取新的URI。
400(Bad Request):表示請求有問題,如參數(shù)錯誤等。
403(Forbidden):表示鑒權(quán)不通過,沒有權(quán)限訪問該資源。
404(Not Found):表示資源不存在。
405(Method Not Allowed):表示該資源不支持當(dāng)前的請求方法。
409(Conflict):表示當(dāng)前請求的某前置條件不符合。
500(Internal Server Error):通用內(nèi)部錯誤。
502(Bad Gateway):網(wǎng)關(guān)錯誤,從上游服務(wù)器收到無效響應(yīng)。
504(Gateway Timeout):網(wǎng)關(guān)超時,在預(yù)期時間內(nèi)沒有收到上游服務(wù)器的響應(yīng)。
……
還有其他HTTP返回碼,可以參考HTTP標(biāo)準(zhǔn)。
只要使用了規(guī)范的REST架構(gòu)風(fēng)格,那么就可以根據(jù)HTTP的標(biāo)準(zhǔn),做出明確的相應(yīng)處理,無需另外制定私有協(xié)議了。既減少了私有協(xié)議的兼容性問題,又能作為標(biāo)準(zhǔn)適用于所有的RESTful架構(gòu)。
5) 返回內(nèi)容REST API的返回內(nèi)容應(yīng)該是資源的表述。
前面說過,同一個資源可以有多種不同格式的表述,如json格式和xml格式,所以返回內(nèi)容應(yīng)該是自描述的。也就是說,在HTTP響應(yīng)的Header中,必須包含Content-type屬性,如application/json、application/xml、text/html等。
另外,REST是“可編程”的Web服務(wù),也就是說,程序可以根據(jù)REST API的返回內(nèi)容,進(jìn)行下一步的操作。例如,查詢author資源,下一步可能是要查詢該作者著作的book資源。所以,如果author資源的表述中包含了該作者著作book資源的URI,則客戶端可以進(jìn)行相應(yīng)的操作。又如,查詢某個地圖資源,地圖資源的表述中如果包含了各方向的相鄰地圖資源,則當(dāng)客戶端的鼠標(biāo)移到屏幕邊緣時,就可以獲取到該方向上的地圖資源了;或者地圖資源的表述中包含景點、餐館等資源URI,則可以進(jìn)行相應(yīng)的操作。
在表述中包含其他資源的URI實現(xiàn)了連通性。連通性可以作為客戶端應(yīng)用狀態(tài)的狀態(tài)引擎,引導(dǎo)客戶端進(jìn)行下一步的操作,帶來了極大的便利。
6) 其他統(tǒng)一接口還有其他方面的原則,本文就不細(xì)講了,感興趣的朋友可以閱讀Fielding的論文。
2. 無狀態(tài)無狀態(tài)約束條件是指兩次請求之間不存在依賴關(guān)系,每一次請求都包含完整的狀態(tài)信息。這里指的狀態(tài)是指客戶端與服務(wù)器之間通信交互的狀態(tài),與資源狀態(tài)無關(guān)。
舉個有狀態(tài)的例子,為了查工資,需要先登錄系統(tǒng)(第一次請求),再輸入查詢密碼(第二次請求)。如果前面兩次請求都通過了,那么調(diào)用查詢接口則可以查詢到工資;否則調(diào)用查詢接口則報未鑒權(quán)的錯誤。查詢工資接口的返回結(jié)果與前面兩次請求的狀態(tài)是關(guān)聯(lián)的,所以是有狀態(tài)的服務(wù)。
而無狀態(tài)的服務(wù),則直接調(diào)用查詢工資接口,在請求中(一般在Header中)帶有鑒權(quán)信息,若鑒權(quán)通過則可查詢到工資,鑒權(quán)不通過則報錯。該請求不依賴于任何前置請求,稱為無狀態(tài)。
REST使用無狀態(tài)約束條件,確保了請求的獨立性和簡單性,減少了很多跨請求的狀態(tài)維護(hù)成本。當(dāng)然,帶來的代價是每次請求可能需要傳輸冗余的信息。
3. 緩存緩存約束條件主要是用于改善網(wǎng)絡(luò)的效率。緩存約束條件要求一個請求的響應(yīng)中的數(shù)據(jù)被隱式地或顯式地標(biāo)記為可緩存的或不可緩存的。如果響應(yīng)是可緩存的,那么客戶端緩存就可以為以后的相同請求重用這個響應(yīng)的數(shù)據(jù),減少了網(wǎng)絡(luò)交互,提高了效率、可伸縮性和用戶感知的性能。
4. 客戶端-服務(wù)器這個約束條件主要是分離用戶界面和數(shù)據(jù)存儲,一方面改善用戶界面跨平臺的可移植性,另一方面簡化服務(wù)器組件,改善系統(tǒng)的可伸縮性。
5. 分層系統(tǒng)分層系統(tǒng)架構(gòu)約束條件將架構(gòu)分為若干層,劃定每一層的邊界,從而降低每一層設(shè)計的復(fù)雜度。同時,通過分層,可以抽象底層的異構(gòu)性,給上層提供統(tǒng)一的接口,簡化上層的邏輯。
6. 按需代碼按需代碼約束條件是指某些場景下,客戶端不清楚資源的處理方法,通過向服務(wù)器請求相應(yīng)的處理代碼來執(zhí)行。這樣可以簡化客戶端開發(fā),允許部署后下載功能代碼來改善系統(tǒng)的可擴(kuò)展性。但是,因為傳輸?shù)氖谴I,降低了可見性,所以是REST的一個可選的架構(gòu)約束條件。
問答
Java中的REST
相關(guān)閱讀
體驗Django REST framework,解讀REST架構(gòu)風(fēng)格
我是怎么一步步用go找出壓測性能瓶頸
當(dāng) MySQL 連接池遇上事務(wù)(一):神秘的幽靈鎖
【每日課程推薦】機(jī)器學(xué)習(xí)實戰(zhàn)!快速入門在線廣告業(yè)務(wù)及CTR相應(yīng)知識
此文已由作者授權(quán)騰訊云+社區(qū)發(fā)布,更多原文請點擊
搜索關(guān)注公眾號「云加社區(qū)」,第一時間獲取技術(shù)干貨,關(guān)注后回復(fù)1024 送你一份技術(shù)課程大禮包!
海量技術(shù)實踐經(jīng)驗,盡在云加社區(qū)!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/77019.html
摘要:因此,誤解幾乎是與之俱來的。這是完全錯誤的。就像所強(qiáng)調(diào)的,對于一個被稱作的來說,狀態(tài)轉(zhuǎn)移管理是一個必須要完成的需求。你可以將其稱為或是,但是請不要把它叫做。 2000年的時候,Douglas Crockford聲明JavaScript是最被誤解的編程語言。這種誤解來源于不良的命名規(guī)范,錯誤設(shè)計,非標(biāo)準(zhǔn)模式等等。因此,誤解幾乎是與之俱來的。 我也在關(guān)于Restful架構(gòu)上發(fā)表了一個相似的...
摘要:在被納入后,與之爭日趨白熱化。一如微軟曾經(jīng)試圖通過在中安裝來排擠,現(xiàn)在正在嘗試將融入到,以此來打擊,,和。如同微軟確確實實提升了的性能。瀏覽器突出了微軟的優(yōu)勢,所以他們在年內(nèi)都沒有繼續(xù)開發(fā)了。 在 Swarm 被納入 Docker 1.12后,Swarm 與 K8S 之爭日趨白熱化。本文作者 Adriaan de Jonge 身為 Xebia CTO ,專精 DevOps 及持續(xù)交付,...
摘要:但也有一些被稱為命令行界面的東西,這可以確保你的應(yīng)用程序可以在服務(wù)器之外運行。與商業(yè)開發(fā)語言相比較,的開發(fā)成本比價低,但是這并非意味著它的質(zhì)量值得懷疑。結(jié)束語這不是所有謊言的終結(jié)者。 PHP是一種非常流行的開源服務(wù)器端腳本語言,你在萬維網(wǎng)看到的大多數(shù)網(wǎng)站都是使用php開發(fā)的。但是,你大概很奇怪的注意到有少部分的人發(fā)誓要離php 遠(yuǎn)遠(yuǎn)的。但是令人更奇怪的是或者很震驚的說他們不用php是因...
摘要:為了防止某些文檔或腳本加載別的域下的未知內(nèi)容,防止造成泄露隱私,破壞系統(tǒng)等行為發(fā)生。模式構(gòu)建函數(shù)響應(yīng)式前端架構(gòu)過程中學(xué)到的經(jīng)驗?zāi)J降牟煌幵谟冢饕獙W⒂谇‘?dāng)?shù)貙崿F(xiàn)應(yīng)用程序狀態(tài)突變。嚴(yán)重情況下,會造成惡意的流量劫持等問題。 今天是編輯周刊的日子。所以文章很多和周刊一樣。微信不能發(fā)鏈接,點了也木有用,所以請記得閱讀原文~ 發(fā)個動圖娛樂下: 使用 SVG 動畫制作游戲 使用 GASP ...
摘要:來源是最流行的用于開發(fā)微服務(wù)的框架。以下依次列出了最佳實踐,排名不分先后。這非常有助于避免可怕的地獄。推薦使用構(gòu)造函數(shù)注入這一條實踐來自的項目負(fù)責(zé)人。保持業(yè)務(wù)邏輯免受代碼侵入的一種方法是使用構(gòu)造函數(shù)注入。 showImg(https://mmbiz.qpic.cn/mmbiz_jpg/R3InYSAIZkHQ40ly9Oztiart2lESCyjCH0JwFRp3oErlYobhibM...
閱讀 732·2021-11-24 10:30
閱讀 1268·2021-09-24 09:48
閱讀 3083·2021-09-24 09:47
閱讀 3602·2019-08-29 17:11
閱讀 2885·2019-08-29 15:38
閱讀 2281·2019-08-29 11:03
閱讀 3609·2019-08-26 12:15
閱讀 1020·2019-08-26 10:45