¿Cómo hacer una solicitud HTTP usando Ruby on Rails?

235

Me gustaría tomar información de otro sitio web. Por lo tanto (tal vez) debería hacer una solicitud a ese sitio web (en mi caso, una solicitud HTTP GET) y recibir la respuesta.

¿Cómo puedo hacer esto en Ruby on Rails?

Si es posible, ¿es un enfoque correcto para usar en mis controladores?

usuario502052
fuente

Respuestas:

330

Puedes usar la Net::HTTPclase de 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
João Silva
fuente
1
¿Qué significa 'req' aquí?
sixty4bit el
18
significa solicitud
Arthur Collé
1
Parece que esto podría ser una solicitud de bloqueo, ¿no?
Scott Eisenberg
donde poner la clave de la API?
user1735921
1
Solo agrego que el www. no debería ser necesario, normalmente no lo es.
JackHasaKeyboard
111

Net :: HTTP está integrado en Ruby, pero seamos sinceros, a menudo es más fácil no usar su engorroso estilo de los años ochenta y probar una alternativa de nivel superior:

stef
fuente
44
O ActiveResource, que viene con Rails.
Marnen Laibow-Koser
8
Me gustaría advertir contra hacerlo, ya que agregará más dependencias a su aplicación de rieles. Más dependencias significa más consumo de memoria y también una superficie de ataque potencialmente más grande. El uso Net::HTTPes engorroso, pero la compensación no vale la pena.
Jason Yeo
3
Esta debería ser la respuesta aceptada. ¿Por qué programar cuando puedes instalar muchas Gemas?
omikes
55
@JasonYeo Muy en desacuerdo. Introducir dependencias significa que no reinventa la rueda y se beneficia del arduo trabajo que otros ya han hecho. Si existe una gema que te facilita la vida, generalmente no hay una buena razón para no usarla.
Marnen Laibow-Koser
1
@JasonYeo La saga leftpad solo sucedió porque NPM ejecutó mal su repositorio y permitió que el autor elimine todos sus paquetes. Los repositorios de paquetes administrados adecuadamente no lo hacen (y de todos modos, es OSS, por lo que puede duplicar fácilmente si lo desea). Es decir, la saga leftpad no es un argumento contra la introducción de dependencias en general, sino contra la gestión deficiente del repositorio. Estoy de acuerdo con su otro punto, que una gran dependencia que hace mucho más de lo que necesita puede ser exagerada por el valor que proporciona.
Marnen Laibow-Koser
92

OpenURI es el mejor; es tan simple como

require 'open-uri'
response = open('http://example.com').read
usuario2454031
fuente
10
Es importante advertir que open-urieso no seguirá a las redirecciones.
yagooar
3
@yagooar que es genial, evita redireccionamientos maliciosos comofile:///etc/passwd
gertas
1
Tenga en cuenta que no cerrará la conexión. Utilice stackoverflow.com/a/4217269/820501
ShockwaveNN
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')
Andrei Andrushkevich
fuente
13

Prefiero httpclient sobre Net :: HTTP.

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

HTTParty es una buena opción si está haciendo una clase que es un cliente para un servicio. Es un mixin conveniente que le brinda el 90% de lo que necesita. Vea cuán cortos son los clientes de Google y Twitter en los ejemplos .

Y para responder a su segunda pregunta: no, no pondría esta funcionalidad en un controlador; en su lugar, usaría un modelo para encapsular los detalles (quizás usando HTTParty) y simplemente llamarlo desde el controlador.

Mark Thomas
fuente
¿Y cómo es posible pasar parámetros de forma segura en la URL? Por ejemplo: http: //www.example.com/index.html? Param1 = test1 & param2 = test2. Luego necesito leer los otros parámetros del sitio web y preparar la respuesta. Pero, ¿cómo puedo leer los parámetros?
user502052
¿Qué quieres decir con que necesitas leer los parámetros del otro sitio web? ¿Cómo sería eso posible? ¿Qué estás intentando lograr?
Marnen Laibow-Koser
8

Mis favoritos dos maneras para captar el contenido de URL son bien OpenURI o Typhoeus .

OpenURI porque está en todas partes, y Typhoeus porque es muy flexible y potente.

el hombre de hojalata
fuente
8

Aquí está el código que funciona si está realizando una llamada API REST detrás de un 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
machzqcq
fuente