對(duì)于運(yùn)行在網(wǎng)絡(luò)上的MIS系統(tǒng)而言,處理數(shù)據(jù)的是整個(gè)系統(tǒng)的主要任務(wù),翻開程序我們可以看到,80%以上的代碼都在處理數(shù)據(jù)的CRUD操作。采用一種什么樣的框架結(jié)構(gòu),能夠使得處理數(shù)據(jù)的操作變得簡單且易理解,這是大部分開發(fā)者尤其是架構(gòu)設(shè)計(jì)者一直以來思考的一個(gè)問題。 REST(Representational State Transfer)是一種編程風(fēng)格,特別是針對(duì)網(wǎng)絡(luò)應(yīng)用的設(shè)計(jì)和開發(fā),采用REST可以顯著降低開發(fā)的復(fù)雜性,提高系統(tǒng)的可伸縮性。 REST是一種獨(dú)特的編程風(fēng)格,與MVC強(qiáng)調(diào)的角色分層概念不同,REST強(qiáng)調(diào)使用統(tǒng)一的規(guī)則來規(guī)范對(duì)資源的操作,兩者互為補(bǔ)充,相符相成,使用 MVC架構(gòu)搭配REST編程風(fēng)格構(gòu)建基于網(wǎng)絡(luò)的MIS系統(tǒng)將在不遠(yuǎn)的為未成為主流。本文著重介紹REST編程風(fēng)格的核心規(guī)則,并且結(jié)合Spring MVC描述REST在實(shí)際應(yīng)用中的代碼形態(tài)。 (本文系作者原創(chuàng),請(qǐng)尊重作者的權(quán)利。本文歡迎轉(zhuǎn)載,如轉(zhuǎn)載必須注明作者及出處!) 使用REST風(fēng)格開發(fā)WEB應(yīng)用程序強(qiáng)調(diào)以下幾點(diǎn)規(guī)則:
首先,在筆者看來,REST定義中的資源就即應(yīng)用程序所處理的數(shù)據(jù)。以訂單管理系統(tǒng)為例,訂單信息就是數(shù)據(jù),同樣客戶信息和產(chǎn)品信息也是數(shù)據(jù),在REST看來這些數(shù)據(jù)都是資源。 REST強(qiáng)調(diào)資源必須有具有唯一名稱和ID,名稱用來區(qū)分不同資源,ID用來定位同類資源中唯一的一條數(shù)據(jù)。在REST中,這些規(guī)則都是通過URI 來描述的。還是以上面的訂單系統(tǒng)為例,我們將訂單信息名稱設(shè)定為order,客戶信息為customer,貨物信息為product,那么就存在幾下的幾 種URI設(shè)計(jì):
我們可以看出REST風(fēng)格URI設(shè)計(jì)的特點(diǎn):http://host/context/資源名稱/[資源ID]。其中資源名稱是必選項(xiàng),資源ID可省略,省略資源ID用來標(biāo)識(shí)一類資源的所有數(shù)據(jù)。 有了資源和用來標(biāo)識(shí)資源的URI后,REST用連接器來標(biāo)識(shí)對(duì)資源的操作。在這里,對(duì)資源的操作分為查詢/獲取、創(chuàng)建、刪除、修改四種。在網(wǎng)絡(luò)編程環(huán)境下,REST用HTTP協(xié)議作為連接器,用HTTP Method(請(qǐng)求方法)標(biāo)識(shí)操作類型:
在完成資源和連接器兩個(gè)核心概念的定義后,我們已經(jīng)可以大體勾勒出REST風(fēng)格編程的基本思路:
還用上面提到的訂單系統(tǒng)為例,請(qǐng)看下面的例子:
簡單的說,URI加上HTTP METHOD構(gòu)成了REST處理數(shù)據(jù)的核心規(guī)則:URI確定了操作的對(duì)象,HTTP METHOD則確定了操作的方式。 與傳統(tǒng)處理數(shù)據(jù)的方式不同,如果不使用REST,那么操作的對(duì)象和操作方式將混合在URL設(shè)計(jì)中,正如首次提出REST概念的Roy T. Fielding博士所說的:“REST允許我們通過url設(shè)計(jì)系統(tǒng)”。事實(shí)上Roy也是Web協(xié)議的主要設(shè)計(jì)者,正是在他的參與下完成了HTTP1.1 規(guī)范的制定。 站在另一個(gè)角度,REST強(qiáng)調(diào)資源(數(shù)據(jù))的概念,一切操作圍繞特定資源展開,離開了資源,REST就失去了存在的意義。在這一點(diǎn)上,REST所倡導(dǎo)的思想與時(shí)下流行的Ajax的編程風(fēng)格有著異曲同工之妙。 Ajax強(qiáng)調(diào)數(shù)據(jù)與展現(xiàn)分離,后臺(tái)應(yīng)用程序致力于生產(chǎn)數(shù)據(jù),前臺(tái)使用腳本進(jìn)行數(shù)據(jù)的展示。對(duì)于數(shù)據(jù)的組織與傳輸Ajax并沒有內(nèi)置的支持。而 REST強(qiáng)調(diào)通過URI將請(qǐng)求與資源進(jìn)行綁定,如果將REST與Ajax技術(shù)進(jìn)行結(jié)合,則可以形成有效的互補(bǔ),我們不妨將上面提到的編程思路進(jìn)行擴(kuò)展,仍 然以獲取ID為1的訂單信息為例:
我們用Spring MVC來實(shí)現(xiàn)上面描述的過程,作為主流的MVC產(chǎn)品,Spring MVC天然支持REST編程風(fēng)格,所以使用Spring MVC來搭建REST風(fēng)格的應(yīng)用程序?qū)⒆兊卯惓:唵巍?/p> Spring MVC使用特殊的標(biāo)注對(duì)Handler對(duì)象進(jìn)行修飾,使得Handler能夠處理REST風(fēng)格的請(qǐng)求,我們來看幾個(gè)例子:
通過上面的例子可以看出,使用Spring MVC編寫REST風(fēng)格的應(yīng)用程序是多么的簡單。 需要我們注意的是,REST要求資源的標(biāo)識(shí)是不變的,也就是說對(duì)于特定的資源,無論對(duì)這個(gè)資源作了什么樣的操作,資源的ID不可以改變。之所以加入 這樣的限制是為了保證URI的一致性。試想如果某個(gè)操作在處理過程中改變了資源的標(biāo)識(shí),那么為了保證規(guī)則的完整性,我們必須付出額外的代價(jià)去在其它的處理 中同步這些變化,這在REST中是不可接受的。 另一方面,REST要求針對(duì)資源的所有操作必須是無狀態(tài)的,URI是確定資源的唯一途徑。如果我們?cè)谔幚頂?shù)據(jù)的過程中融入了狀態(tài)數(shù)據(jù),那么針對(duì)同一資源的URI就會(huì)出現(xiàn)二義性,這將與REST的定義背道而馳。 |
|