簡(jiǎn)介
當(dāng)今的應(yīng)用程序不僅需要和基于瀏覽器的客戶端互操作,還需要和其他應(yīng)用程序互操作。為實(shí)現(xiàn)互操作性,web 應(yīng)用程序通常提供一個(gè) web 服務(wù) API。web 服務(wù) API 通過(guò)一個(gè)網(wǎng)絡(luò)(比如 Internet)提供對(duì)應(yīng)用程序 的遠(yuǎn)程訪問(wèn)。直到最近,web 服務(wù) API 還使用重型、復(fù)雜的基于 SOAP 的 web 服務(wù)集成,這種 web 服務(wù),不僅沒(méi)有什么優(yōu)點(diǎn),而且還需要很長(zhǎng)時(shí)間才能實(shí)現(xiàn)。帶有基于 Representational State Transfer (REST) 服務(wù)的 Rails 框架有一種更簡(jiǎn)單、更快捷的方法通過(guò) Active Resource 來(lái)實(shí)現(xiàn)和使用 web 服務(wù)。
在 Rails 實(shí)現(xiàn)了 RESTful 以后,現(xiàn)在只需通過(guò)一個(gè) Rails 動(dòng)作就能提供一個(gè)特定資源的不同內(nèi)容類型(或者表示)。這種方法有以下好處:
- 一個(gè)資源的各種表示狀態(tài)。
- 對(duì)不基于瀏覽器的 HTML 客戶端的附加支持在 Controller 視圖中得到了簡(jiǎn)化。
- 應(yīng)用程序之間以及與新客戶端之間的互操作性。
在本文中,您將了解 REST、SOAP、Rails Active Resource,以及如何提高多個(gè)應(yīng)用程序之間的互操作性。
Ruby on Rails
Ruby on Rails(也稱為 Rails 或 RoR)是一個(gè)用 Ruby 語(yǔ)言編寫(xiě)的開(kāi)源 web 應(yīng)用程序框架。Ruby on Rails 旨在幫助開(kāi)發(fā)人員更輕松快捷地開(kāi)發(fā)和部署 web 應(yīng)用程序,與其他語(yǔ)言和框架相比,Rails 框架進(jìn)行了幾個(gè)假設(shè)。其目的是使用敏捷開(kāi)發(fā)的方法,實(shí)現(xiàn)快速開(kāi)發(fā)。
Rails 框架合并了以下幾個(gè)包:
- Active Record:一個(gè)對(duì)象關(guān)系映射層,用于數(shù)據(jù)庫(kù)相關(guān)訪問(wèn)和功能;
- Action Pack:一個(gè)控制器和視圖功能管理器;
- Action Mailer:一個(gè)電子郵件處理器;
- Active Support
- Active Resource:提供 web 服務(wù)(即 Action Web 服務(wù))。
Web 服務(wù)
Web 服務(wù)是使用開(kāi)放協(xié)議通信的應(yīng)用程序組件,它們可以被其他應(yīng)用程序使用。web 服務(wù)是簡(jiǎn)單 APIs ,可以使用 HTML 進(jìn)行訪問(wèn),并在承載請(qǐng)求服務(wù)的遠(yuǎn)程系統(tǒng)上執(zhí)行。web 服務(wù)是不同平臺(tái)上、以不同語(yǔ)言編寫(xiě)、不同系統(tǒng)上的各種應(yīng)用程序的關(guān)鍵集成點(diǎn)。
REST 不是一個(gè)協(xié)議;它是利用 World Wide Web 的技術(shù)和協(xié)議的大型聯(lián)網(wǎng)軟件的一種架構(gòu)風(fēng)格。REST 描述如何定義和處理分布式數(shù)據(jù)對(duì)象(或資源),強(qiáng)調(diào)簡(jiǎn)單的信息交換和可伸縮性。REST 架構(gòu)描述該該架構(gòu)上應(yīng)用的 6 個(gè)約束。
另一方面,SOAP 是一個(gè)協(xié)議規(guī)范,用于在計(jì)算機(jī)網(wǎng)絡(luò)中交換 web 服務(wù)的實(shí)現(xiàn)中的結(jié)構(gòu)化信息。它依賴 XML 作為其消息格式,通常依賴其他應(yīng)用程序?qū)訁f(xié)議(RPC 和 HTTP)進(jìn)行消息協(xié)商和傳輸。SOAP 可以形成 web 服務(wù)協(xié)議堆棧的基礎(chǔ)層,提供用于在其上構(gòu)建 web 服務(wù)的基礎(chǔ)消息傳遞框架。
REST 與 SOAP
下表展示了 REST 和 SOAP 之間的一些區(qū)別。
REST 依賴一個(gè)單一的應(yīng)用程序協(xié)議(HTTP)、幾個(gè) URI、以及幾種通過(guò) XML 標(biāo)準(zhǔn)化的數(shù)據(jù)格式。它采用成熟的 HTTP 方法(比如 GET 和 POST)來(lái)指揮應(yīng)用程序。REST 開(kāi)發(fā)人員使用 URI 來(lái)創(chuàng)建一個(gè)公共基礎(chǔ),以便應(yīng)用程序使用 HTTP 和 XML 來(lái)共享數(shù)據(jù),而不是為應(yīng)用程序創(chuàng)建一種機(jī)器可讀的標(biāo)準(zhǔn)方法來(lái)發(fā)現(xiàn)和使用遠(yuǎn)程系統(tǒng)上的應(yīng)用程序組件(這是 SOAP 用于 web 服務(wù)的方法)。REST 開(kāi)發(fā)人員使用 XML 文檔而不是應(yīng)用程序方法調(diào)用來(lái)告訴分布式程序如何相互使用數(shù)據(jù)。
REST 支持者指出,使用 SOAP 協(xié)議直接訪問(wèn)遠(yuǎn)程程序的功能必定會(huì)遇到 DCOM 和 Common Object Request Broker Architecture 等之前分布式計(jì)算架構(gòu)所遇到的互操作性問(wèn)題。
Active Resource
在對(duì) web 應(yīng)用程序在服務(wù)器和客戶機(jī)應(yīng)用程序之間的通信采用 RESTful 方法之前,SOAP 和其他 XML-RPC 形式被用于通過(guò)一個(gè) API 進(jìn)行通信。Rails 2 引入的 Active Resource 替代了 Action Web Service。Active Resource 完全理解 RESTful 路由和 XML 表示。它是一個(gè)類,用于將 RESTful 資源映射為 Rails 應(yīng)用程序中的模型。Active Resource 提供一些工具來(lái)快速、輕松地使用遵守 Rails RESTful URI 結(jié)構(gòu)和協(xié)議約定的基于 REST 的 web 服務(wù)。Active Resource 將來(lái)自任何合格服務(wù)的響應(yīng)映射到富 Ruby 對(duì)象。Active Resource 還提供輕松執(zhí)行基本的 CRUD 功能需要的全部生命周期方法。
CRUD 操作分別對(duì)應(yīng) HTTP 方法 POST、GET、PUT 和 DELETE。而且,Active Resource 對(duì)這些 HTTP 方法中的每個(gè)方法都有一個(gè)方法。它們接收與 CRUD 相同的參數(shù),但返回收到的 XML 的一個(gè)哈希表。Active Resource 對(duì)象本質(zhì)上是 REST web 服務(wù)器的前端。它通過(guò)向服務(wù)器回調(diào) HTTP 調(diào)用并將 XML 結(jié)果解析回一個(gè) Ruby 對(duì)象中來(lái)獲取并修改它的數(shù)據(jù)。
清單 1 展示了一個(gè)最小 Active Resource 示例。假設(shè)有一個(gè)圖書(shū)館應(yīng)用程序,每個(gè)類別作為一個(gè)不同的客戶端,且 Indian History 是其中一個(gè)類別。
清單 1. Active Resource 示例
class IndianHistory ActiveResource::Base
self.site = “http://indian-history.com”
end
ActiveResource 擁有與 Active Record 相同的方法。在上面的代碼樣例中,類 IndianHistory 正繼承自 ActiveResource Base。在第二行中,self.site 持有包含 IndianHistory 圖書(shū)的 URI 的站點(diǎn)值。在本例中,這個(gè) URI 是 http://indian-history.com(假設(shè)這個(gè) URI 是帶有必要模型和控制器動(dòng)作的另一個(gè) Rails 應(yīng)用程序)。
現(xiàn)在,這個(gè)類被映射到站點(diǎn)值定位的 RESTful 資源,您現(xiàn)在可以操作 IndianHistory 類的資源。要獲取 Indian History 下的所有圖書(shū)列表,您將調(diào)用它的 find 方法,它類似于 Active Record find 方法。
>> books = IndianHistory.find (:all)
這個(gè) Active Resource 模塊類似于 Active Record 模塊;它們擁有相同的風(fēng)格。
假設(shè)您正在尋找標(biāo)題為 “Akbar” 的圖書(shū),可以使用以下代碼:
>> books = IndianHistory.find(:all, :params => { :title => “Akbar”}}
與 Active Record find 方法中的常規(guī) :conditions 子句不同,本示例使用了 :params,且 URL 是 GET http://indian-history.com/indian_histories.xml?title=Akbar。
Active Resource 不僅限于檢索數(shù)據(jù)。您可以使用所有 CRUD 操作。在腳本/控制臺(tái)中,您可以使用:
>> IndianHistory.create (:title => “Jhansi Stories”, :amount => 233.00, :available => 0)
上述代碼行將使用提供的數(shù)據(jù)向 create 動(dòng)作中存在清單 2 中的代碼的控制器創(chuàng)建一個(gè) HTTP POST。
清單 2. Create
class IndianHistoryController ActiveResource::Base
def create
@book = IndianHistory.new (params [:indian_history])
respond_to do |format|
if @book.save
flash[:notice] = “New title added successfully”
format.html { redirect_to(@book) }
format.xml { render :xml => @book, :status => :created}
else
format.html { render :action => “new” }
format.xml { render :xml => @book.errors, :status => :unprocessable_entity}
end
end
end
end
如果圖書(shū)記錄成功保存,將返回新創(chuàng)建的、狀態(tài)碼為 HTTP 201 的記錄,并將使用新創(chuàng)建的記錄重定向視圖。
同樣,您也可以更新和刪除記錄,主要您擁有執(zhí)行管理的權(quán)限和訪問(wèn)權(quán)。
對(duì)于 Update 操作,在腳本/控制臺(tái)中使用:
清單 3. Update
>> book= IndianHistory.find (2)
>> book.available = 1
>> book.save
>> book = IndianHistory.find (2)
>> book.available # => 1
您更新了圖書(shū)的可用性并保存記錄。ActiveResource 和 ActiveRecord 之間有一個(gè)細(xì)微差別:ActiveResource 中沒(méi)有方法 save 和 update。
最后,下面的語(yǔ)句將從數(shù)據(jù)庫(kù)移除記錄。
>> IndianHistory.delete(2)
除了上面介紹的基本操作外,Active Resource 還允許通過(guò)設(shè)置一個(gè) HTTP 頭部來(lái) 支持 HTTP 基本身份驗(yàn)證。假如用戶名和密碼被設(shè)置且在身份驗(yàn)證失敗時(shí)拋出錯(cuò)誤,則客戶機(jī)和服務(wù)器連接的安全檢查就能通過(guò)每個(gè)連接上的 Active Resource 身份驗(yàn)證來(lái)完成?;镜纳矸蒡?yàn)證也可以輕松實(shí)現(xiàn)。
結(jié)束語(yǔ)
在本文中,您了解了 web 服務(wù)、REST、SOAP 和 Rails Active Resource。一個(gè)簡(jiǎn)單的示例向您展示了 CRUD 操作。
Ruby on Rails Active Resource 包以一種 RESTful 方式提供多個(gè) web 應(yīng)用程序之間的輕松通信。除了 CRUD 操作外,它還允許您創(chuàng)建自定義動(dòng)作。
您可能感興趣的文章:- 舉例理解Ruby on Rails的頁(yè)面緩存機(jī)制
- 在Ruby on Rails中優(yōu)化ActiveRecord的方法
- 舉例講解Ruby中迭代器Iterator的用法