寫在前面的話
這個(gè)問題看起來就顯得有些萌,或者說類似的問題都有些不靠譜上陕,世上哪有那么多一定的事情桩砰,做開發(fā)都不一定做多久呢,所以說如果你有這個(gè)疑問的話是真真有點(diǎn)兒不著調(diào)释簿,不過可能也就是隨口一問吧亚隅,沒有深究的必要。既然有人問這個(gè)庶溶,那么就再用一篇文章談?wù)凴ESTful吧煮纵,既然談懂鸵,就不能只是談其優(yōu)點(diǎn),也不能一味的吹捧行疏,也講一下自己的一些理解和不足的地方匆光。
規(guī)范、易讀酿联、簡(jiǎn)潔终息?
Spring+SpringMVC+MyBatis+easyUI整合進(jìn)階篇(一)設(shè)計(jì)一套好的RESTful API
Spring+SpringMVC+MyBatis+easyUI整合進(jìn)階篇(二)RESTful API實(shí)戰(zhàn)筆記(接口設(shè)計(jì)及Java后端實(shí)現(xiàn))
Spring+SpringMVC+MyBatis+easyUI整合進(jìn)階篇(三)使用ajax方法實(shí)現(xiàn)form表單的提交
Spring+SpringMVC+MyBatis+easyUI整合進(jìn)階篇(四)RESTful API實(shí)戰(zhàn)筆記(前端代碼修改)
前文中已經(jīng)談了RESTful不少的優(yōu)點(diǎn),也做了代碼更新贞让,首先周崭,REST強(qiáng)調(diào)HTTP應(yīng)當(dāng)以資源為中心,并且規(guī)范了資源URI的風(fēng)格震桶;規(guī)范了HTTP請(qǐng)求動(dòng)作(PUT休傍,POST等)的使用征绎,具有對(duì)應(yīng)的語義蹲姐;遵循REST規(guī)范的Web應(yīng)用將會(huì)獲得下面好處:URL具有很強(qiáng)可讀性的,具有自描述性人柿;資源描述與視圖的松耦合柴墩;可提供OpenAPI,便于第三方系統(tǒng)集成凫岖,提高互操作性江咳;如果提供無狀態(tài)的服務(wù)接口,可提高應(yīng)用的水平擴(kuò)展性哥放;
總結(jié)下來:規(guī)范歼指、易讀,但是這兩個(gè)優(yōu)點(diǎn)也帶來一些不盡如人意的"反效果":
- 因?yàn)镽ESTful規(guī)范較為明確且有一定的"強(qiáng)制性",這種限制反而導(dǎo)致設(shè)計(jì)uri變得復(fù)雜了甥雕,尤其是復(fù)雜的關(guān)系踩身,操作,資源集合社露,硬性套用rest原則設(shè)計(jì)非常困難挟阻。
- 對(duì)于RESTful的爭(zhēng)論無處不在,都在討論正確性和規(guī)范性峭弟,即使和同事之間也會(huì)有類似的爭(zhēng)執(zhí)附鸽,當(dāng)我們?cè)跔?zhēng)論Restful風(fēng)格到底如何設(shè)計(jì)才是正宗時(shí),發(fā)現(xiàn)心中的困惑不僅沒有降低瞒瘸,反而增加了坷备。
- RESTful思想及其所倡導(dǎo)的規(guī)范很正確,但是使用者的行為太刻意了反而導(dǎo)致這個(gè)東西變了味道情臭,爭(zhēng)來爭(zhēng)去就是為了證明自己的理解和使用最"正宗"击你。
RESTful中的模棱兩可
前一個(gè)段落可能有些過于概念化了玉组,還是舉一些具體的例子吧。
案例一
其實(shí)丁侄,RESTful中也存在著許多的模棱兩可惯雳,也有很多不是那么讓開發(fā)人員舒服的地方,有人會(huì)去糾結(jié)查詢鸿摇、增加石景、修改、刪除(對(duì)應(yīng)的方法就是get拙吉、post潮孽、put、delete)筷黔,個(gè)人認(rèn)為這并不完全正確往史,因?yàn)檫@個(gè)想法把開發(fā)工作中的業(yè)務(wù)場(chǎng)景過于簡(jiǎn)單化和模板化了,我們開發(fā)的功能就只實(shí)現(xiàn)這四類操作嗎佛舱、如果遇到一些不能完全對(duì)應(yīng)上這四種方式的業(yè)務(wù)該怎么辦呢椎例?
- 發(fā)短信、支付请祖、用戶登錄認(rèn)證订歪,該用get、post肆捕、put刷晋、delete中的哪一個(gè)HTTP動(dòng)詞?
- login和logout應(yīng)該怎么REST化慎陵?
- 驗(yàn)證碼發(fā)送該如何定義uri眼虱?
類似的問題還有很多,感覺很多朋友會(huì)遇到類似的問題席纽,心里面也有一些不確定該如何去做捏悬,其實(shí)在理解了REST后,這些并不是什么無解的難題胆筒,只是思維方式要轉(zhuǎn)換一下: login和logout其實(shí)只是對(duì)token或者cookie資源的創(chuàng)建和刪除邮破;業(yè)務(wù)的uri如何選擇HTTP動(dòng)詞也要靈活變通,規(guī)范是死的仆救,人是活的抒和,按照自己的理解去做,如果后期發(fā)現(xiàn)錯(cuò)誤即使糾正就好了彤蔽。不過摧莽,雖然API如何編寫是開發(fā)者的自由,但如果一個(gè)API在url里放一堆動(dòng)詞顿痪、資源設(shè)計(jì)混亂镊辕、各種亂用HTTP Method和Status Code油够,就太不像話了,規(guī)范嘛還是要遵守的征懈,說了這么多理解上的偏差石咬,其實(shí)代碼質(zhì)量才是最重要的,有些手段其實(shí)只是讓代碼看起來比較優(yōu)雅的手段而已卖哎。
案例二
以上是針對(duì)于RESTful理解和設(shè)計(jì)上的一個(gè)例子鬼悠,具體工作中還有其他的例子嗎?也是很多的亏娜,比如焕窝,比較棘手的一個(gè)問題:跨域資源共享 CORS。
在實(shí)際進(jìn)行跨域請(qǐng)求時(shí)维贺,經(jīng)常會(huì)遇到類似 No 'Access-Control-Allow-Origin' header is present on the requested resource.
這樣的報(bào)錯(cuò):
這個(gè)問題并不是因?yàn)镽ESTful引起的炼邀,也不能通過修改RESTful的規(guī)范去解決摹菠,舉這個(gè)例子的原因是因?yàn)樵诮涌诘腞ESRful化時(shí)也遇到過這個(gè)問題涝缝,解決辦法就不在本文中列舉了川背,有興趣的朋友可以看一下跨域資源共享 CORS 詳解這篇文章媒区,以后有時(shí)間會(huì)把解決方案整理出來的逛尚。
一些需要重視的安全性問題
當(dāng)然茄螃,不止是以上的兩個(gè)問題盯桦,前一個(gè)段落主要是講述了一下理解和具體使用上的問題雪猪,這一段講一下可能引發(fā)的安全性問題栏尚。
遺漏了對(duì)資源從屬關(guān)系的檢查
一個(gè)典型的RESTful的URL會(huì)用資源名加上資源的id編號(hào)來標(biāo)識(shí)其唯一性,就像這樣:/users/{userid}
只恨,例如:/users/100
一般而言用戶只能查看自己的用戶信息译仗,而不允許查看其它用戶的信息。在這種情況下官觅,攻擊者很可能會(huì)嘗試把這個(gè)URL里面的USER ID從100修改為其他數(shù)值纵菌,以期望應(yīng)用返回指定用戶的信息。不過由于這個(gè)安全風(fēng)險(xiǎn)太顯而易見休涤,絕大多數(shù)應(yīng)用都會(huì)對(duì)當(dāng)前請(qǐng)求者的身份進(jìn)行校驗(yàn)咱圆,看其是否是編號(hào)為100的用戶,校驗(yàn)成功才返回URL中指定的用戶信息功氨,否則會(huì)拒絕當(dāng)前請(qǐng)求序苏。
不經(jīng)意間泄露的業(yè)務(wù)信息
以查看用戶信息的RESTful URL為例:/users/100。由于用戶ID是一個(gè)按序遞增的數(shù)字捷凄,因此攻擊者既可以通過ID知道目前應(yīng)用中的用戶規(guī)模忱详,也可以分別在月初和月末的時(shí)候注冊(cè)一個(gè)用戶,并對(duì)比兩個(gè)用戶的ID即可知道當(dāng)前這個(gè)月有多少新增用戶跺涤。同理匈睁,如果訂單號(hào)也是按序自增的數(shù)字监透,攻擊者可以了解到一定時(shí)間范圍內(nèi)的訂單量。
這類ID并不會(huì)給應(yīng)用造成任何技術(shù)上的威脅航唆,只是通過ID泄露出來的信息對(duì)于你的業(yè)務(wù)而言可能非常敏感胀蛮。解決辦法是不使用按序遞增的數(shù)字作為ID,而是使用具有隨機(jī)性糯钙、唯一性醇滥、不可預(yù)測(cè)性的值作為ID,最常見的做法就是使用UUID超营。
參考RESTful架構(gòu)風(fēng)格下的4大常見安全問題
選擇適合自己的方式
Spring+SpringMVC+MyBatis+easyUI整合進(jìn)階篇(五)記錄一下從懵懂到理解RESTful的過程
前一篇博客中也提到了很多其他的方式鸳玩,比如傳統(tǒng)的MVC開放形式,比如webservice演闭,比如rpc調(diào)用不跟,RESTful也只是其中的一種而已,這些選項(xiàng)中并沒有高下之分米碰,無非是多種約定俗成的標(biāo)準(zhǔn)窝革,傳統(tǒng)MVC開發(fā)著舒服就按MVC模式來開發(fā),習(xí)慣用RPC就用RPC吕座,能理解和接受REST就用REST虐译。
前幾篇文章中描述了RESTful那么多的優(yōu)點(diǎn),現(xiàn)在又說大可不必使用吴趴,前文又提到RESTful是好的設(shè)計(jì)實(shí)踐漆诽,現(xiàn)在又是另外一種說法,不是自相矛盾嗎锣枝?
這是我的文章厢拭,我肯定要按照我的一些想法寫啊,可能有不對(duì)的地方撇叁,前文中提到的是好的設(shè)計(jì)實(shí)踐也是我的個(gè)人想法和理解供鸠,這篇的開頭就說了,不能只談優(yōu)點(diǎn)陨闹,所以又列舉了一些不足吧楞捂,我寫文章不是挑口水,很沒必要趋厉,選擇適合自己的技術(shù)和規(guī)范就好寨闹。
套用網(wǎng)絡(luò)上比較流行的一句話:
聽了很多道理卻依然過不好一生。
作為一名開發(fā)人員觅廓,自己動(dòng)手去實(shí)踐才是硬道理鼻忠,別人說什么都不要全盤接受,你要想想適不適合你,適不適合你目前做的項(xiàng)目帖蔓,鞋合不合適只有腳知道矮瘟,just do it!
結(jié)語
優(yōu)點(diǎn)也好,缺點(diǎn)也罷塑娇,雖然看似也總結(jié)了不少澈侠,但都是個(gè)人見解,肯定還有一些遺漏的地方?jīng)]有講清楚埋酬,還請(qǐng)見諒哨啃。
回答文章一開始的問題,是不是一定要用呢写妥?是不是一定要遵循其規(guī)則呢拳球?如果不能解決你所面對(duì)的問題,不能提高和提升代碼質(zhì)量珍特、提升工作效率祝峻,其實(shí)大可不必如此介懷,不用就是了扎筒。
首發(fā)于我的個(gè)人博客莱找,新的項(xiàng)目演示地址:perfect-ssm,登錄賬號(hào):admin,密碼:123456
如果有問題或者有一些好的創(chuàng)意,歡迎給我留言嗜桌,也感謝向我指出項(xiàng)目中存在問題的朋友奥溺,本篇主要講述了個(gè)人對(duì)于RESTful的理解。
如果你想繼續(xù)了解該項(xiàng)目可以查看整個(gè)系列文章Spring+SpringMVC+MyBatis+easyUI整合系列文章,也可以到我的GitHub倉庫或者開源中國代碼倉庫中查看源碼及項(xiàng)目文檔骨宠。