2012-08-02 95 views
6

如何使用JSON服務作爲Rails 3.2應用程序的模型?使用JSON服務作爲Rails模型

我想將模型方法鏈接到JSON請求,例如,

  • MyModel.create生成一個JSON請求創建一個新的記錄
  • MyModel.find生成一個JSON請求檢索記錄和解碼JSON響應爲模型對象

什麼是首選方式構建這種類型的功能?我正在看的一個選項是創建一個自定義DataMapper適配器。

謝謝。

更新:我不能使用的ActiveResource,因爲這需要JSON服務以某種方式作出反應,它不會在這種情況下
注意。

回答

3

簡答:取決於您的JSON服務。

服務RESTful,對於初學者?如果是這樣,你很幸運。 ActiveResource是dead,所以我不會建議使用它,但代碼本身會爲創建一組包裝方法提供一個很好的起點,如createfind來訪問您的API並以ActiveRecord創建和查詢記錄的方式操作記錄D B。如果你的API是RESTful的,這相對容易,因爲rails is built around RESTful-ness,所以兩者之間的映射變得更加乾淨。

This article總結說得好:

Rails使得它非常容易構建遵循REST原則,並與Web瀏覽器和可編程的Web工作同樣出色的Web服務。事實上,很多簡單直接來自於遵循這些原則。我們不必告訴我們的客戶如何創建,讀取,更新或刪除資源,這些都使用正確的HTTP方法。我們所要做的就是將我們的客戶指向正確的地方。

如果您的服務是 REST風格,從我想在其他問題提出的意見來看,也許是這樣,那麼你有你的工作等着你。 ActiveModel將不會爲您完成這項工作:createActiveRecord::Persistence中定義,並且findActiveRecord::FinderMethods中定義。 他們不在ActiveModel中。ActiveResource能夠很容易地重現它們,因爲它可以假定它所連接的服務類型(即它是RESTful,還有其他一些東西)。

提供加載ActiveModel什麼是所有其他的東西,使鋼軌的處理模式非常有用:它的驗證系統,序列化方法,屬性變化髒跟蹤, 回調(before_saveafter_save等),翻譯/本地化,等等。這些都是非常有用的功能,但它們仍然會給你帶來包裝你的API調用的問題。

因此,這裏就是我會建議的基礎上,我雖然是有限的經驗(參見我的有關最終注):

  1. 首先,需要在你的API的密切關注,並弄清楚它是如何被關閉REST風格。如果是而不是 RESTful,則必須考慮如何解決此問題,以便您可以將其視爲REST式服務。 O'Reilly的RESTful Web Services(特別是第2章「編寫Web服務客戶端」。有。您可能想要使用像 FaradayHTTParty這樣的寶石來實際向API發出請求,而不是直接使用Net :: HTTP。 (我從來沒有使用過DataMapper,所以不能對此進行評論。)
  2. 包含你想用來使你的包裝類更像一個rails模型的ActiveModel的任何元素:驗證,序列化等。在Rails 4中,你可以實際上包括使用新準系統ActiveModel::Model的所有內容。

這將爲您提供使用JSON服務作爲Rails模型的很多方法。爲了記錄,我在實際實現這種事情方面的經驗僅限於構建用於訪問XML API的API包裝器(在工作中)。包裝器有一個包含ActiveModel驗證器的類,用於驗證對API的查詢。我發現ActiveModel驗證器對於確保正確訪問API非常有用,但是封裝僅用於從API獲取記錄,而不是實際創建或更新它們,因此該接口比我期望的要容易得多你會建設。

+0

謝謝你這麼全面的回答。幸運的是,JSON服務是RESTful的,只是它沒有以ActiveResource預期的方式做出響應。現在我會避免使用ActiveResource,因爲我知道它已經死了,而是讀取您鏈接到的DZone文章。再次感謝! – gjb 2012-08-14 17:01:23

+0

哦,這是個好消息!在這種情況下,任務不應該太困難。即使您沒有使用ActiveResource,也可以嘗試查看代碼以瞭解其工作原理。 – 2012-08-14 20:46:30

+0

如果您仍在處理此問題,請參閱其他一些可能有用的寶石:https://github.com/filtersquad/api_smith https://github.com/remiprev/her https://github.com/ apotonick/roar – 2012-10-31 13:53:47

0

我只是在我的寶石「otrs_connector」中做到這一點......它不會爲你的服務工作,但它可以給你一個想法如何做到這一點...我採取的方法可能不是最好的,需要重構一下,但它確實有效,並且非常好。

+0

感謝的例子,我要看看這個。 – gjb 2012-08-03 09:13:47

1

我想你要找的是ActiveResource,你可以用它來代替ActiveRecord有一個RESTful API JSON工作看this linkthis (apidock)

+0

謝謝。不幸的是,這似乎要求JSON API以某種方式響應,而我正在使用的那個不會。例如,如果創建了一條新記錄,而不是新記錄的JSON表示,則它會以「OK」響應。 – gjb 2012-08-03 09:12:52

1

做到這一點,最好的辦法是實現一個加載ActiveModel。這railscast涵蓋了基本知識。

+0

謝謝,我會看看。 ActiveModel比DataMapper有什麼優勢? – gjb 2012-08-11 19:11:52

+0

ActiveModel包含在Rails中,所以您可以更好地支持它。 – 2012-08-11 21:59:25

0

如果web服務不在正常的「Rails方式」做事情上,我會推薦HTTParty。向網絡服務做出Proxy是非常容易的,無論您希望如何迴應。

舉例來說,這裏是他們的訪問Twitter的時間表

class Twitter 
    include HTTParty 
    base_uri 'twitter.com' 

    def initialize(u, p) 
    @auth = {:username => u, :password => p} 
    end 

    # which can be :friends, :user or :public 
    # options[:query] can be things like since, since_id, count, etc. 
    def timeline(which=:friends, options={}) 
    options.merge!({:basic_auth => @auth}) 
    self.class.get("/statuses/#{which}_timeline.json", options) 
    end 

    def post(text) 
    options = { :query => {:status => text}, :basic_auth => @auth } 
    self.class.post('/statuses/update.json', options) 
    end 
end 

twitter = Twitter.new(config['email'], config['password']) 
pp twitter.timeline 
+0

謝謝,這是一個有趣的選擇,但我更喜歡JSON服務的功能就像傳統的Rails模型。 – gjb 2012-08-14 22:30:58