若是要說什麼是REST的話,那最好先從Web(萬維網)提及。html
什麼是Web呢?讀者能夠查看維基百科的詞條(http://zh.wikipedia.org/zh-cn/Web),具體的我就很少說了。總之,Web是咱們在互聯網上最經常使用的服務,甚至在某些人的心中,互聯網就是Web。固然,Web只是互聯網的一部分而已,只是你們用的最多而已,咱們訪問的全部網站都是基於Web。java
那麼,Web和REST之間究竟有什麼關係呢?咱們接下來將聊聊組成Web的幾大基礎技術,URI(統一資源標識符,用來標識資源)、HTTP(超文本傳輸/轉移協議,用來操做資源)、Hypertext(超文本,用來描述資源的內容與狀態,咱們能夠用HTML、XML、JSON或者自定義格式的文原本描述任何一個資源)。程序員
那咱們再來看看什麼是REST呢?其實REST並非一種新興的技術語言,也不是什麼新的技術框架。準確來講說REST只是一種概念、風格或者約束,是迴歸HTTP自己的建議。web
REST是由Roy Thomas Fieding在他的博士論文《Architectural Styles and the Design of Network-based Software Architectures》(《架構風格與基於網絡的軟件架構設計》)中提出的一種架構思想。Roy Fielding是Apache基金會的合做創做者,同時也是HTTP、URI等Web基礎協議的主要設計者。從Roy Fielding的背景,我想你們就應該能瞭解到REST與Web之間的關係了吧。的確,在REST中咱們關注技術實際上也只是URI、HTTP、Hypertext而已。瀏覽器
Roy在他的論文中提出了一個RESTful應用應該具有的幾點約束。安全
Roy認爲,只有具有了上面的約束的應用才能算是REST應用,其實如今好多所謂的REST應用或服務,其實並不能算是真正的REST應用。服務器
我發現,其實目前不少所謂的REST應用,只是RPC而已,出現這樣的狀況其實很正常,由於RPC實際上更符合通常程序員的思惟。其實REST和RPC之間仍是有很大的差別的,下面咱們說一說REST和RPC之間的區別。網絡
經過上面的介紹,你們應該對REST有一些最基本的瞭解,因爲RESTf應用的這些約束,咱們能夠很輕易的瞭解和使用REST的服務(只要你瞭解HTTP)。架構
其實,咱們常常容易犯一個錯誤就是,當咱們瞭解了一個新的技術,就會用這個技術來解決全部的問題。有一句諺語是這麼來講的:「在錘子的眼裏,全部的東西都是釘子」,其實REST也只是咱們工具箱裏面的其中的一個工具而已,但願不要把它當作咱們惟一的工具。那麼咱們就來聊聊適合使用REST的應用場景和不適合使用REST的應用場景。框架
在我看來REST最適合的應用場景實際上是須要對外暴露服務的時候,這個時候,咱們能夠充分利用REST的自描述、無狀態、惟一標識等特性來提供清晰、友好的API,並且如今的Jesery、RESTEasy等JAX-RS框架也提供了OAuth的支持,基本上可以保證服務安全。
最不適合的應用場景是對性能要求高的系統內部之間的服務調用,當你在這個時候使用REST的話,那麼REST全部的特性都會變成拖累。這個時候,仍是須要選擇更底層的通訊協議和方式會更好一些,好比ICE。這樣的錯誤,我曾經犯過,後來經過很長時間的努力才慢慢的將這個錯誤改過來。
當咱們要規劃一個REST服務的時候,其中最關鍵的概念其實就是「資源」。
資源是什麼呢?廣義上講,任何事物只要它有用,那麼它就是資源。狹義的講(在Web環境中),它是一個能夠存放、鏈接在計算機上,能夠經過比特流進行操控的實體。一個實體想成爲資源,它必須有一個URI。在這裏URI包含了兩重含義:1)它是資源的名稱 2)它是資源的地址。
在咱們規劃URI的時候,有幾點但願你們可以注意一下:
當咱們定義好資源以後,接下來要作的事情就是定義操做資源的方法以及資源的表述格式了。
使用HTTP提供的基本方法來對資源進行操做,通常的操做定義以下:POST(建立資源)、GET(獲取資源)、PUT(修改資源)、DELETE(刪除)。它們正好對應了CRUD。
對資源的表述,通常的選擇會是XML,可是我更加推薦使用JSON來表述資源。在網絡中的傳輸量也小,並且也便於JavaScript來解析,並且如今其餘語言解析也是很是方便的事情。不過,最關鍵的仍是佔用更少的資源,讓一樣的資源可以服務更多的人。
下面的這張圖就很好的說明了REST中最重要的圍繞資源的三角關係。
在InfoQ上有一篇很好的文章來介紹如何規劃REST服務《如何獲取(GET)一杯咖啡——星巴克REST案例分析》,估計你們看完這篇文章,應該對如何規劃REST服務會有更深的認識。
如今REST的框架也很是多,推薦你們使用Jersey和RESTEasy來建立本身的REST服務。
這兩個框架都出自名門,Jersey是由SUN提供的JAX-RS實現參考,對JAX-RS支持的最爲充分和快速,基本上全部的JAX-RS的新特性都會在Jersey裏第一個體現出來,並且提供了至關全的例子讓你學習。RESTEasy則是由JBoss開源的項目,它一樣有不少優勢,並且文檔也比Jersey更好一些,可是和他JBoss應用服務器綁定的比較緊密,這點我我的不太喜歡,若是是熟悉JBoss應用服務器的人能夠選擇RESTEasy,它給人的感受更加成熟一些,不像Jersey會很快的加入新的特性。不過,須要根據我的本身的喜愛來選擇。
如何使用Jersey來快速建立REST應用,參見經過Jersey快速構建REST應用,如何使用RESTEasy快速建立REST應用,參見使用RESTEasy快速建立REST應用。
以前我也提到了使用REST的最佳的場景是對外提供公開的服務,也就是所謂的OpenAPI。一旦開放了API,咱們就很難控制這些API的使用及其調整了,若是在開放這些API以前考慮的不周到的話,那麼後期的維護那就會是一個很是麻煩的事情了。因此,當咱們決定要開放API的時候,那麼咱們必定要注意一些事情,下面的這些算是個人經驗總結。
對外暴露API時,須要注意版本規劃,以便之後API的升級和維護。API的版本規劃,在開始開放API的以前,是一件很容易被忽視的。可是一旦你的API開放以後,那麼你就會發現,沒有對開放的API進行版本規劃,是一件很是愚蠢的事情。當你的API使用的人愈來愈多,當你的開放的API愈來愈多,一旦某個API要升級,輸入和輸出發生變化的時候,你根本不知道該通知誰來升級,解決問題的時候也很是麻煩。
一樣,因爲對外暴露API以後,你很難控制API被調用的次數和意圖,須要在一些關鍵的API被調用的次數和頻率上進行控制,以避免受到惡意的攻擊。可是,到底次數和頻率應該控制在一個什麼樣的程度,就要看你的API的關鍵程度以及負載能力了,每一個系統都會有本身的評判,只要你掌握好了這個尺度,應該都不會有問題的。