Ruby-on-rails 在另一个域上使用 RESTful Web 服务的正确“Rails 方式”是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/748614/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the proper "Rails Way" to consume a RESTful web service on another domain?
提问by Mike Farmer
I would like to write a Ruby on Rails application that consumes a RESTful web service API performs some logic on the result and then displays that data on my view. For example, let's say I wanted to write a program that did a search on search.twitter.com. Using pure ruby I might create the following method:
我想编写一个 Ruby on Rails 应用程序,它使用 RESTful Web 服务 API 对结果执行一些逻辑,然后在我的视图中显示该数据。例如,假设我想编写一个在 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
I'm tempted to just drop that method into my Rails controller as a private method, but part of me thinks that there is a better, more "Rails" way to do this. Is there a best practice approach or is this really the best way?
我很想将该方法作为私有方法放入我的 Rails 控制器中,但我的一部分认为有一种更好、更“Rails”的方式来做到这一点。是否有最佳实践方法或者这真的是最好的方法?
采纳答案by Kyle Boon
There is a plugin/gem called HTTParty that I've used for several projects.
有一个名为 HTTParty 的插件/gem,我已用于多个项目。
http://johnnunemaker.com/httparty/
http://johnnunemaker.com/httparty/
HTTParty lets you easily consume any web service and parses results into a hash for you. Then you can use the hash itself or instantiate one or more model instances with the results. I've done it both ways.
HTTParty 可让您轻松使用任何 Web 服务并将结果解析为哈希。然后你可以使用散列本身或用结果实例化一个或多个模型实例。我两种方法都做过。
For the twitter example, your code would look like this:
对于 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')
As a last point, you could use your code above also, but definitely include the code in a model as opposed to a controller.
最后一点,您也可以使用上面的代码,但一定要将代码包含在模型中,而不是控制器中。
回答by Ethan Heilman
Restclientis a really nice solution to this problem.
Restclient是这个问题的一个很好的解决方案。
require 'rest_client'
RestClient.get 'http://example.com/resource'
RestClient.get 'http://example.com/resource', {:params => {:id => 50, 'foo' => 'bar'}}
From the readme.
从自述文件。
回答by Adam Alexander
if the remote RESTful web service was also created with Ruby on Rails, ActiveResourceis the way to go.
如果远程 RESTful Web 服务也是使用 Ruby on Rails 创建的,则ActiveResource是最佳选择。
回答by Adam Alexander
In response to your Twitter example, there is a Twitter Gemthat would help to automate this for you.
针对您的 Twitter 示例,有一个Twitter Gem可以帮助您自动执行此操作。
回答by Duke
I think Faraday deserves a mention here. Really nice interface, and powerful concept of middleware.
我认为法拉第在这里值得一提。非常好的界面,以及强大的中间件概念。

