有人提了一個問題:一定要RESTful嗎?
寫在前麵的話
這個問題看起來就顯得有些萌,或者說類似的問題都有些不靠譜,世上哪有那麼多一定的事情,做開發都不一定做多久呢,所以說如果你有這個疑問的話是真真有點兒不著調,不過可能也就是隨口一問吧,沒有深究的必要。既然有人問這個,那麼就再用一篇文章談談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其實隻是對session資源或者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。
選擇適合自己的方式
Spring+SpringMVC+MyBatis+easyUI整合進階篇(五)記錄一下從懵懂到理解RESTful的過程
前一篇博客中也提到了很多其他的方式,比如傳統的MVC開放形式,比如webservice,比如rpc調用,RESTful也隻是其中的一種而已,這些選項中並沒有高下之分,無非是多種約定俗成的標準,傳統MVC開發著舒服就按MVC模式來開發,習慣用RPC就用RPC,能理解和接受REST就用REST。
前幾篇文章中描述了RESTful那麼多的優點,現在又說大可不必使用,前文又提到RESTful是好的設計實踐,現在又是另外一種說法,不是自相矛盾嗎?
這是我的文章,我肯定要按照我的一些想法寫啊,可能有不對的地方,前文中提到的是好的設計實踐也是我的個人想法和理解,這篇的開頭就說了,不能隻談優點,所以又列舉了一些不足吧,我寫文章不是挑口水,很沒必要,選擇適合自己的技術和規範就好。
套用網絡上比較流行的一句話:聽了很多道理卻依然過不好一生。
作為一名開發人員,自己動手去實踐才是硬道理,別人說什麼都不要全盤接受,你要想想適不適合你,適不適合你目前做的項目,鞋合不合適隻有腳知道,just do it!
結語
優點也好,缺點也罷,雖然看似也總結了不少,但都是個人見解,肯定還有一些遺漏的地方沒有講清楚,還請見諒。
回答文章一開始的問題,是不是一定要用呢?是不是一定要遵循其規則呢?如果不能解決你所麵對的問題,不能提高和提升代碼質量、提升工作效率,其實大可不必如此介懷,不用就是了。
首發於我的個人博客,編輯於2017年10月13日晚11:37分。
本文作者:佚名
來源:51CTO
最後更新:2017-11-02 16:04:05
上一篇:
深度學習框架中的魔鬼:探究人工智能係統中的安全問題
下一篇:
IT團隊需要的10個關鍵安全能力
Java線程之鎖研究
九度題目1449:確定比賽名次
Android 獲取網絡狀態的工具類
iPhone開發中的多語言化
Oracle數據庫導出報componet'SET_NO_OUTLINES'must be declared的錯
【zz】函數對象
編譯mysql提示錯誤:configure: error: No curses/termcap library found 解決方法
未能正確加載“VSTS for Database Professionals Sql Server Data-tier Application”包。
深入淺出: 大小端模式
筆記本鍵盤失靈