Spring+SpringMVC+MyBatis+easyUI整合進階篇(六)一定要RESTful嗎?


作者:13
GitHub:https://github.com/ZHENFENG13
版權聲明:本文為原創文章,未經允許不得轉載。

寫在前面的話

這個問題看起來就顯得有些萌,或者說類似的問題都有些不靠譜,世上哪有那么多一定的事情,做開發都不一定做多久呢,所以說如果你有這個疑問的話是真真有點兒不着調,不過可能也就是隨口一問吧,沒有深究的必要。既然有人問這個,那么就再用一篇文章談談RESTful吧,既然談,就不能只是談其優點,也不能一味的吹捧,也講一下自己的一些理解和不足的地方。

規范、易讀、簡潔?

Spring+SpringMVC+MyBatis+easyUI整合進階篇(一)設計一套好的RESTful API
Spring+SpringMVC+MyBatis+easyUI整合進階篇(二)RESTful API實戰筆記(接口設計及Java后端實現)
Spring+SpringMVC+MyBatis+easyUI整合進階篇(三)使用ajax方法實現form表單的提交
Spring+SpringMVC+MyBatis+easyUI整合進階篇(四)RESTful API實戰筆記(前端代碼修改)
前文中已經談了RESTful不少的優點,也做了代碼更新,首先,REST強調HTTP應當以資源為中心,並且規范了資源URI的風格;規范了HTTP請求動作(PUT,POST等)的使用,具有對應的語義;遵循REST規范的Web應用將會獲得下面好處:URL具有很強可讀性的,具有自描述性;資源描述與視圖的松耦合;可提供OpenAPI,便於第三方系統集成,提高互操作性;如果提供無狀態的服務接口,可提高應用的水平擴展性;

總結下來:規范、易讀,但是這兩個優點也帶來一些不盡如人意的"反效果":

  • 因為RESTful規范較為明確且有一定的"強制性",這種限制反而導致設計uri變得復雜了,尤其是復雜的關系,操作,資源集合,硬性套用rest原則設計非常困難。
  • 對於RESTful的爭論無處不在,都在討論正確性和規范性,即使和同事之間也會有類似的爭執,當我們在爭論Restful風格到底如何設計才是正宗時,發現心中的困惑不僅沒有降低,反而增加了。
  • RESTful思想及其所倡導的規范很正確,但是使用者的行為太刻意了反而導致這個東西變了味道,爭來爭去就是為了證明自己的理解和使用最"正宗"。

RESTful中的模棱兩可

前一個段落可能有些過於概念化了,還是舉一些具體的例子吧。

案例一

其實,RESTful中也存在着許多的模棱兩可,也有很多不是那么讓開發人員舒服的地方,有人會去糾結查詢、增加、修改、刪除(對應的方法就是get、post、put、delete),個人認為這並不完全正確,因為這個想法把開發工作中的業務場景過於簡單化和模板化了,我們開發的功能就只實現這四類操作嗎、如果遇到一些不能完全對應上這四種方式的業務該怎么辦呢?

  • 發短信、支付、用戶登錄認證,該用get、post、put、delete中的哪一個HTTP動詞?
  • login和logout應該怎么REST化?
  • 驗證碼發送該如何定義uri?

類似的問題還有很多,感覺很多朋友會遇到類似的問題,心里面也有一些不確定該如何去做,其實在理解了REST后,這些並不是什么無解的難題,只是思維方式要轉換一下: login和logout其實只是對token或者cookie資源的創建和刪除;業務的uri如何選擇HTTP動詞也要靈活變通,規范是死的,人是活的,按照自己的理解去做,如果后期發現錯誤即使糾正就好了。不過,雖然API如何編寫是開發者的自由,但如果一個API在url里放一堆動詞、資源設計混亂、各種亂用HTTP Method和Status Code,就太不像話了,規范嘛還是要遵守的,說了這么多理解上的偏差,其實代碼質量才是最重要的,有些手段其實只是讓代碼看起來比較優雅的手段而已。

案例二

以上是針對於RESTful理解和設計上的一個例子,具體工作中還有其他的例子嗎?也是很多的,比如,比較棘手的一個問題:跨域資源共享 CORS。

在實際進行跨域請求時,經常會遇到類似 No 'Access-Control-Allow-Origin' header is present on the requested resource.這樣的報錯:
跨域

這個問題並不是因為RESTful引起的,也不能通過修改RESTful的規范去解決,舉這個例子的原因是因為在接口的RESRful化時也遇到過這個問題,解決辦法就不在本文中列舉了,有興趣的朋友可以看一下跨域資源共享 CORS 詳解這篇文章,以后有時間會把解決方案整理出來的。

一些需要重視的安全性問題

當然,不止是以上的兩個問題,前一個段落主要是講述了一下理解和具體使用上的問題,這一段講一下可能引發的安全性問題。

遺漏了對資源從屬關系的檢查

一個典型的RESTful的URL會用資源名加上資源的id編號來標識其唯一性,就像這樣:/users/{userid},例如:/users/100

一般而言用戶只能查看自己的用戶信息,而不允許查看其它用戶的信息。在這種情況下,攻擊者很可能會嘗試把這個URL里面的USER ID從100修改為其他數值,以期望應用返回指定用戶的信息。不過由於這個安全風險太顯而易見,絕大多數應用都會對當前請求者的身份進行校驗,看其是否是編號為100的用戶,校驗成功才返回URL中指定的用戶信息,否則會拒絕當前請求。

不經意間泄露的業務信息

以查看用戶信息的RESTful URL為例:/users/100。由於用戶ID是一個按序遞增的數字,因此攻擊者既可以通過ID知道目前應用中的用戶規模,也可以分別在月初和月末的時候注冊一個用戶,並對比兩個用戶的ID即可知道當前這個月有多少新增用戶。同理,如果訂單號也是按序自增的數字,攻擊者可以了解到一定時間范圍內的訂單量。

這類ID並不會給應用造成任何技術上的威脅,只是通過ID泄露出來的信息對於你的業務而言可能非常敏感。解決辦法是不使用按序遞增的數字作為ID,而是使用具有隨機性、唯一性、不可預測性的值作為ID,最常見的做法就是使用UUID。

參考RESTful架構風格下的4大常見安全問題

選擇適合自己的方式

Spring+SpringMVC+MyBatis+easyUI整合進階篇(五)記錄一下從懵懂到理解RESTful的過程
前一篇博客中也提到了很多其他的方式,比如傳統的MVC開放形式,比如webservice,比如rpc調用,RESTful也只是其中的一種而已,這些選項中並沒有高下之分,無非是多種約定俗成的標准,傳統MVC開發着舒服就按MVC模式來開發,習慣用RPC就用RPC,能理解和接受REST就用REST。

前幾篇文章中描述了RESTful那么多的優點,現在又說大可不必使用,前文又提到RESTful是好的設計實踐,現在又是另外一種說法,不是自相矛盾嗎?

這是我的文章,我肯定要按照我的一些想法寫啊,可能有不對的地方,前文中提到的是好的設計實踐也是我的個人想法和理解,這篇的開頭就說了,不能只談優點,所以又列舉了一些不足吧,我寫文章不是挑口水,很沒必要,選擇適合自己的技術和規范就好。

套用網絡上比較流行的一句話:

聽了很多道理卻依然過不好一生。

作為一名開發人員,自己動手去實踐才是硬道理,別人說什么都不要全盤接受,你要想想適不適合你,適不適合你目前做的項目,鞋合不合適只有腳知道,just do it!

結語

網站的持續運行需要各項基礎設施的搭建,而服務期的續費和維護及各種配套服務的購買也需要一定的費用,希望朋友們給予一點支持,謝謝!

支付寶:zhifubao微信支付:wxpay

優點也好,缺點也罷,雖然看似也總結了不少,但都是個人見解,肯定還有一些遺漏的地方沒有講清楚,還請見諒。

回答文章一開始的問題,是不是一定要用呢?是不是一定要遵循其規則呢?如果不能解決你所面對的問題,不能提高和提升代碼質量、提升工作效率,其實大可不必如此介懷,不用就是了。

首發於我的個人博客,新的項目演示地址:perfect-ssm,登錄賬號:admin,密碼:123456

如果有問題或者有一些好的創意,歡迎給我留言,也感謝向我指出項目中存在問題的朋友,本篇主要講述了個人對於RESTful的理解。

如果你想繼續了解該項目可以查看整個系列文章Spring+SpringMVC+MyBatis+easyUI整合系列文章,也可以到我的GitHub倉庫或者開源中國代碼倉庫中查看源碼及項目文檔。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM