2012-08-02 97 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