¿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?

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

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:


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


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

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.


¿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

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.