【问题标题】:What is the proper "Rails Way" to consume a RESTful web service on another domain?在另一个域上使用 RESTful Web 服务的正确“Rails 方式”是什么?
【发布时间】:2009-04-14 17:31:02
【问题描述】:

我想编写一个使用 RESTful Web 服务 API 的 Ruby on Rails 应用程序,对结果执行一些逻辑,然后在我的视图中显示该数据。例如,假设我想编写一个在 search.twitter.com 上进行搜索的程序。使用纯红宝石我可能会创建以下方法:

def run(search_term='', last_id=0)
  @results = []
  url = URI.parse("http://search.twitter.com")
  res = Net::HTTP.start(url.host, url.port) do |http|
    http.get("/search.json?q=#{search_term}&since_id=#{last_id.to_s}")
  end
  @results = JSON.parse res.body
end

我很想将该方法作为私有方法放入我的 Rails 控制器,但我的一部分认为有更好、更“Rails”的方法来做到这一点。是否有最佳实践方法,或者这真的是最好的方法吗?

【问题讨论】:

    标签: ruby-on-rails rest


    【解决方案1】:

    有一个名为 HTTParty 的插件/gem,我已在多个项目中使用它。

    http://johnnunemaker.com/httparty/

    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
    
    # usage examples.
    twitter = Twitter.new('username', 'password')
    twitter.post("It's an HTTParty and everyone is invited!")
    twitter.timeline(:friends, :query => {:since_id => 868482746})
    twitter.timeline(:friends, :query => 'since_id=868482746')
    

    最后一点,您也可以使用上面的代码,但绝对要将代码包含在模型中,而不是控制器中。

    【讨论】:

    • 我喜欢这颗宝石。这使得使用 Web 服务非常灵活。我仍然有一个问题是 Rails 是否已经内置了一些东西来做到这一点?似乎这是一件很常见的事情,可以尝试这样做,他们会有办法做到这一点。
    • 另外,请原谅我的 Rails noobieness :),我将如何将其设置为模型。我只使用 ActiveRecord 访问数据库的模型。
    • rails 核心没有内置任何东西。模型只是一个类 - 只需在模型目录中创建一个类,不要从 ActiveRecord:Base 类继承。您不会包含任何 AR 优点,但这是在 rails 应用程序中使用 Web 服务的一种非常常见的模式
    • 谢谢!我会试一试。感谢您的帮助。
    • 我现在已经开始使用 restclient 来做这类事情,因为 HTTParty 越来越陈旧,而 restclient 更容易使用。
    【解决方案2】:

    Restclient 是一个非常好的解决这个问题的方法。

    require 'rest_client'
    RestClient.get 'http://example.com/resource'
    RestClient.get 'http://example.com/resource', {:params => {:id => 50, 'foo' => 'bar'}}
    

    来自readme

    【讨论】:

    • 我非常同意 RestClient。它确实是一个处理所有 API 调用的很棒的框架。
    • 好东西。来自 iOS,这正是我想要的。
    • 比起 HTTParty,我更喜欢 RestClient。感觉更接地气,对我来说没有那么神奇。 YMMV
    【解决方案3】:

    如果远程 RESTful Web 服务也是使用 Ruby on Rails 创建的,那么ActiveResource 就是要走的路。

    【讨论】:

    • 我不能做出这样的假设,因为我想从许多不同的网站提取数据,而我不知道底层框架是什么。但是我会看一下 ActiveResource,因为我知道 Rails。谢谢!
    • 实际上,不需要使用 Rails 创建远程 RESTful 服务来使 ActiveResource 工作。底层实现无关紧要。
    • 这绝对是 Rails 使用 RESTful 资源的首选方式。保持代码干净并符合 MVC。
    【解决方案4】:

    针对您的 Twitter 示例,有一个 Twitter Gem 可以帮助您自动执行此操作。

    【讨论】:

      【解决方案5】:

      我认为法拉第在这里值得一提。非常漂亮的界面和强大的中间件概念。

      https://github.com/lostisland/faraday

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-19
        • 1970-01-01
        • 1970-01-01
        • 2011-04-07
        • 2015-10-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多