Ruby HTTP get with params

2019-04-19 15:11发布

问题:

How can I send HTTP GET request with parameters via ruby?

I have tried a lot of examples but all of those failed.

回答1:

I know this post is old but for the sake of those brought here by google, there is an easier way to encode your parameters in a URL safe manner. I'm not sure why I haven't seen this elsewhere as the method is documented on the Net::HTTP page. I have seen the method described by Arsen7 as the accepted answer on several other questions also.

Mentioned in the Net::HTTP documentation is URI.encode_www_form(params):

# Lets say we have a path and params that look like this:
path = "/search"
params = {q: => "answer"}

# Example 1: Replacing the #path_with_params method from Arsen7
def path_with_params(path, params)
   encoded_params = URI.encode_www_form(params)
   [path, encoded_params].join("?")
end

# Example 2: A shortcut for the entire example by Arsen7
uri = URI.parse("http://localhost.com" + path)
uri.query = URI.encode_www_form(params)
response = Net::HTTP.get_response(uri)

Which example you choose is very much dependent on your use case. In my current project I am using a method similar to the one recommended by Arsen7 along with the simpler #path_with_params method and without the block format.

# Simplified example implementation without response
# decoding or error handling.

require "net/http"
require "uri"

class Connection
  VERB_MAP = {
    :get    => Net::HTTP::Get,
    :post   => Net::HTTP::Post,
    :put    => Net::HTTP::Put,
    :delete => Net::HTTP::Delete
  }

  API_ENDPOINT = "http://dev.random.com"

  attr_reader :http

  def initialize(endpoint = API_ENDPOINT)
    uri = URI.parse(endpoint)
    @http = Net::HTTP.new(uri.host, uri.port)
  end

  def request(method, path, params)
    case method
    when :get
      full_path = path_with_params(path, params)
      request = VERB_MAP[method].new(full_path)
    else
      request = VERB_MAP[method].new(path)
      request.set_form_data(params)
    end

    http.request(request)
  end

  private

  def path_with_params(path, params)
    encoded_params = URI.encode_www_form(params)
    [path, encoded_params].join("?")
  end

end

con = Connection.new
con.request(:post, "/account", {:email => "test@test.com"})
=> #<Net::HTTPCreated 201 Created readbody=true> 


回答2:

I assume that you understand the examples on the Net::HTTP documentation page but you do not know how to pass parameters to the GET request.

You just append the parameters to the requested address, in exactly the same way you type such address in the browser:

require 'net/http'

res = Net::HTTP.start('localhost', 3000) do |http|
  http.get('/users?id=1')
end
puts res.body

If you need some generic way to build the parameters string from a hash, you may create a helper like this:

require 'cgi'

def path_with_params(page, params)
  return page if params.empty?
  page + "?" + params.map {|k,v| CGI.escape(k.to_s)+'='+CGI.escape(v.to_s) }.join("&")
end

path_with_params("/users", :id => 1, :name => "John&Sons")
# => "/users?name=John%26Sons&id=1"


回答3:

I guess it is failing because of other reasons, some real example will help to understand the problem. Anyway you can send a get request with parameters very easy by using the nice_http gem: https://github.com/MarioRuiz/nice_http

require 'nice_http'

http = NiceHttp.new('https://reqres.in')

resp = http.get "/api/users?page=2&other=true&more=Doomi"

pp resp.code
pp resp.data.json