6

如何使用 JSON 服务作为 Rails 3.2 应用程序的模型?

我想将模型方法链接到 JSON 请求,例如

  • MyModel.create生成 JSON 请求以创建新记录
  • MyModel.find生成 JSON 请求以检索记录并将 JSON 响应解码为模型对象

构建此类功能的首选方法是什么?我正在考虑的一个选项是创建一个自定义DataMapper适配器。

谢谢。

更新:
请注意,我不能使用 ActiveResource,因为这需要 JSON 服务以某种方式响应,而在这种情况下它不需要。

4

5 回答 5

3

简短的回答:这取决于您的 JSON 服务。

对于初学者来说,服务是 RESTful 的吗?如果是这样,你很幸运。ActiveResource已死,因此我不建议使用它,但代码本身将为创建一组包装器方法(如访问您的 API 和操作记录)提供一个很好的起点,就像 ActiveRecord 在数据库中创建和查询记录create一样。find如果您的 API 是 RESTful 的,这相对容易,因为rails 是围绕 RESTful-ness 构建的,因此两者之间的映射变得更加清晰。

这篇文章总结的很好:

Rails 使得构建遵循 REST 原则的 Web 服务变得非常容易,并且与 Web 浏览器和可编程 Web 一样好。事实上,很多这种简单性直接来自于遵循这些原则。我们不必告诉我们的客户如何创建、读取、更新或删除资源,所有这些都来自使用正确的 HTTP 方法。我们所要做的就是将我们的客户指向正确的位置。

如果您的服务不是RESTful 的,从我认为其他问题的评论来看可能是这种情况,那么您的工作将为您完成。ActiveModel 不会为您完成这项工作:createActiveRecord::Persistencefind定义,在ActiveRecord::FinderMethods中定义。它们不在 ActiveModel 中。ActiveResource 能够相当容易地复制它们,因为它假设了它所连接的服务类型(即它是 RESTful 的,加上其他一些东西)。

ActiveModel 提供的所有其他东西使 rails 在处理模型方面如此有用:它的验证系统、序列化方法、属性更改的脏跟踪、回调(before_saveafter_save等)、翻译/本地化等等。这些都是非常有用的功能,但它们仍然给您留下了包装 API 调用的问题。

因此,根据我虽然有限的经验,这就是我的建议(请参阅我的最后说明):

  1. 首先,仔细查看您的 API 并找出它与 RESTful 的距离有多近。如果它不是RESTful,您将不得不考虑如何解决这个问题,以便您可以将其视为 RESTful 服务。关于如何做到这一点的一个很好的参考是 O'Reilly 的RESTful Web 服务(特别是第 2 章,“编写 Web 服务客户端”。)
  2. 围绕它创建一个 API 包装器,以实现createfind以及您想要拥有的任何其他类似 ActiveRecord 的功能。您可能希望使用像 FaradayHTTParty这样的 gem来实际向 API 发出请求,而不是直接使用 Net::HTTP。(我从未使用过 DataMapper,因此无法对此发表评论。)
  3. 包含您想要使用的任何 ActiveModel 元素,以使您的包装类更像一个 rails 模型:验证、序列化等。在 Rails 4 中,您实际上可以使用新的准系统ActiveModel::Model包含所有内容。

这将为您提供将 JSON 服务用作 Rails 模型的大部分方法。

作为记录,我在实际实现这种事情方面的经验仅限于构建一个用于访问 XML API 的 API 包装器(正在开发中)。包装器有一个类,其中包括用于验证 API 查询的 ActiveModel 验证器。我发现 ActiveModel 验证器对于保证 API 被正确访问非常有用,但包装器仅用于从 API 获取记录,而不是实际创建或更新它们,因此接口比我预期的要容易得多你会建造的。

于 2012-08-13T21:22:07.943 回答
1

我认为您正在寻找的是ActiveResource,您可以使用它而不是使用ActiveRecordRESTful JSON API 看到这个链接这个(apidock)

于 2012-08-03T05:28:38.593 回答
1

最好的方法是实现一个 ActiveModel。这个railscast涵盖了基础知识。

于 2012-08-11T09:08:30.660 回答
0

我在我的 gem“ otrs_connector ”中做到了这一点......它不适用于您的服务,但它可以让您了解如何做到这一点......我采用的方法可能不是最好的,需要重构有点,但它确实有效,而且做得很好。

于 2012-08-02T23:50:07.763 回答
0

如果 Web 服务超出了正常的“Rails 方式”做事,我会推荐HTTParty。为响应您想要的响应的 Web 服务创建代理非常容易。

例如,这是他们访问 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
于 2012-08-14T18:55:56.707 回答