Como fazer uma solicitação HTTP usando Ruby on Rails?


235

Eu gostaria de receber informações de outro site. Portanto (talvez) eu deveria fazer uma solicitação para esse site (no meu caso, uma solicitação HTTP GET) e receber a resposta.

Como posso fazer isso no Ruby on Rails?

Se for possível, é uma abordagem correta para usar nos meus controladores?

Respostas:


330

Você pode usar a Net::HTTPclasse Ruby :

require 'net/http'

url = URI.parse('http://www.example.com/index.html')
req = Net::HTTP::Get.new(url.to_s)
res = Net::HTTP.start(url.host, url.port) {|http|
  http.request(req)
}
puts res.body

1
o que o 'req' significa aqui?
sixty4bit 4/14

18
significa pedido
Arthur Collé

1
Parece que isso pode ser uma solicitação de bloqueio, não?
Scott Eisenberg

onde colocar a tecla api?
user1735921

1
Apenas adicionando que o www. não deve ser necessário, normalmente não é.
JackHasaKeyboard

111

O Net :: HTTP está embutido no Ruby, mas, convenhamos, muitas vezes é mais fácil não usar seu estilo pesado da década de 1980 e tentar uma alternativa de nível superior:


4
Ou ActiveResource, que vem com o Rails!
Marnen Laibow-Koser

8
Gostaria de advertir contra isso, pois você adicionará mais dependências ao seu aplicativo de trilhos. Mais dependências significam mais consumo de memória e também uma superfície de ataque potencialmente maior. O uso Net::HTTPé complicado, mas a troca não vale a pena.
Jason Yeo

3
Essa deve ser a resposta aceita. Por que programar quando você pode simplesmente instalar muitas Gems?
omikes

5
@JasonYeo Discordo totalmente. Introduzir dependências significa que você não reinventa a roda e se beneficia do trabalho duro que outras pessoas já fizeram. Se existe uma jóia que facilita sua vida, geralmente não há uma boa razão para não usá-la.
Marnen Laibow-Koser

1
@JasonYeo A saga do leftpad aconteceu apenas porque o NPM executou mal o seu repositório e deixou o autor excluir todos os seus pacotes. Os repositórios de pacotes gerenciados corretamente não fazem isso (e, de qualquer maneira, é OSS, para que você possa espelhar facilmente, se quiser). Ou seja, a saga do leftpad não é um argumento contra a introdução de dependências em geral, mas sim contra o gerenciamento inadequado do repositório. Concordo com seu outro ponto, que uma grande dependência que faz muito mais do que você precisa pode ser um exagero pelo valor que ela oferece.
Marnen Laibow-Koser


82
require 'net/http'
result = Net::HTTP.get(URI.parse('http://www.example.com/about.html'))
# or
result = Net::HTTP.get(URI.parse('http://www.example.com'), '/about.html')

13

Eu prefiro httpclient sobre Net :: HTTP.

client = HTTPClient.new
puts client.get_content('http://www.example.com/index.html')

HTTParty é uma boa opção se você estiver criando uma classe que é cliente para um serviço. É uma combinação conveniente que oferece 90% do que você precisa. Veja como os clientes do Google e Twitter são curtos nos exemplos .

E para responder à sua segunda pergunta: não, eu não colocaria essa funcionalidade em um controlador - eu usaria um modelo, se possível, para encapsular os detalhes (talvez usando HTTParty) e simplesmente chamá-lo do controlador.


E como é possível passar parâmetros com segurança no URL? Por exemplo: http: //www.example.com/index.html? Param1 = teste1 & param2 = teste2. Então, preciso ler os outros parâmetros do site e preparar a resposta. Mas como posso ler parâmetros?
precisa saber é o seguinte

Como assim, você precisa ler os parâmetros do outro site? Como isso seria possível? O que você está tentando alcançar?
Marnen Laibow-Koser

8

Minhas duas maneiras favoritas de capturar o conteúdo de URLs são OpenURI ou Typhoeus .

OpenURI porque está em todo lugar, e Typhoeus porque é muito flexível e poderoso.


8

Aqui está o código que funciona se você estiver fazendo uma chamada API REST atrás de um proxy:

require "uri"
require 'net/http'

proxy_host = '<proxy addr>'
proxy_port = '<proxy_port>'
proxy_user = '<username>'
proxy_pass = '<password>'

uri = URI.parse("https://saucelabs.com:80/rest/v1/users/<username>")
proxy = Net::HTTP::Proxy(proxy_host, proxy_port, proxy_user, proxy_pass)

req = Net::HTTP::Get.new(uri.path)
req.basic_auth(<sauce_username>,<sauce_password>)

result = proxy.start(uri.host,uri.port) do |http|
http.request(req)
end

puts result.body
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.