2016-04-28 2 views
1

У меня есть следующий запрос завитка:Воспроизведите локон запрос в рубин

curl -X POST -H "Content-Type: application/json" -H "charset: UTF-8" -H "Cache-Control: no-cache" -d '{"destId":684}' https://viatorapi.viator.com/service/search/products?apiKey=VIATOR_API_KEY 

Этот завиток запрос работает правильно. Если я попытаюсь переместить apiKey параметр хэш данных, я получаю сообщение об ошибке apiKey. Например,

curl -X POST -H "Content-Type: application/json" -H "charset: UTF-8" -H "Cache-Control: no-cache" -d '{"destId":684, "apiKey":VIATOR_API_KEY}' https://viatorapi.viator.com/service/search/products 

Я не могу понять, в чем разница между этими двумя запросами.

Очевидно, что вместо VIATOR_API_KEY я использую реальную ценность.

И теперь я пытаюсь воспроизвести этот запрос на завивку в рубине.

require 'uri' 
require 'net/http' 
require 'json' 

API_KEY  = ENV['VIATOR_API_KEY'] 
BASE_URL  = "http://viatorapi.viator.com/service" 
path   = "/search/products" 

# Full reference 
uri = URI.parse "#{BASE_URL}#{path}?apiKey=#{API_KEY}" 

http = Net::HTTP.new(uri.host, uri.port) 
request = Net::HTTP::Post.new(uri.request_uri) 
request.initialize_http_header({"Content-type" => "application/json", "charset" => "UTF-8", "Cache-Control" => "no-cache"}) 
request.set_form_data('destId' => 684) 

response = http.request(request) 

puts response.body 

if response.code == "200" 
    # Do something 
end 

Теперь я получаю 415 ошибку неподдерживаемых Тип носителя.

Любые идеи в чем проблема?

UPDATE

Я понял, что это было из-за. Перед установка параметров данных request.set_form_data('destId' => 684) заголовка запроса является

{"content-type"=>["application/json"], "charset"=>["UTF-8"], "cache-control"=>["no-cache"]} 

после

{"content-type"=>["application/x-www-form-urlencoded"], "charset"=>["UTF-8"], "cache-control"=>["no-cache"]} 

Так или иначе этого set_form_data измененного содержания типа

+0

Эта ошибка HTTP возникает, когда Content-Type неверен. Я бы это проверить. – squiguy

+0

Вы JSON кодируете данные своей формы? Я не думаю, что Net :: HTTP делает это для вас. 'JSON.dump ('destId' => 684)' вместо этого. – tadman

+0

[cURB] (https://github.com/taf2/curb) - хороший выбор, когда вы пытаетесь сделать curl-ish вещи в Ruby. –

ответ

3

Я думаю, что вы можете использовать камень Typhoeus является завиток обертка довольно легко перевести локон запрос, вот пример для запроса

require 'typhoeus' 

request = Typhoeus::Request.new(
    "https://viatorapi.viator.com/service/search/products", 
    method: :post, 
    params: { apiKey: "VIATOR_API_KEY" }, 
    body: { destId: 684}, 
    headers: { 'Content-Type' => "application/json", charset: "UTF-8",'Cache-Control' => "no-cache" } 
) 

request.on_complete do |response| 
    if response.success? 
    # hell yeah 
    elsif response.timed_out? 
    # aw hell no 
    log("got a time out") 
    elsif response.code == 0 
    # Could not get an http response, something's wrong. 
    log(response.return_message) 
    else 
    # Received a non-successful http response. 
    log("HTTP request failed: " + response.code.to_s) 
    end 
end 

request.run 

#curl -X POST -H "Content-Type: application/json" -H "charset: UTF-8" -H "Cache-Control: no-cache" -d '{"destId":684}' https://viatorapi.viator.com/service/search/products?apiKey=VIATOR_API_KEY 

исполняющего:

irb(main):112:0' => #<Typhoeus::Response:0x007fd46396b920 @options={:httpauth_avail=>0, :total_time=>0.933899, :starttransfer_time=>0.93374, :appconnect_time=>0.52442, :pretransfer_time=>0.5244530000000001, :connect_time=>0.25838099999999997, :namelookup_time=>0.000657, :redirect_time=>0.0, :effective_url=>"https://viatorapi.viator.com/service/search/products?apiKey=VIATOR_API_KEY", :primary_ip=>"54.165.220.73", :response_code=>200, :request_size=>269, :redirect_count=>0, :return_code=>:ok, :response_headers=>"HTTP/1.1 200 OK\r\nDate: Thu, 28 Apr 2016 17:24:23 GMT\r\nContent-Type: application/json;charset=ISO-8859-1\r\nContent-Length: 372\r\nVary: Accept-Encoding\r\n\r\n", :response_body=>"{\"errorReference\":\"~21084218484370761736807418\",\"data\":null,\"dateStamp\":\"2016-04-28T10:24:23+0000\",\"errorType\":\"EXCEPTION\",\"errorMessage\":[\"API ACCESS DENIED!!! Api Key 'VIATOR_API_KEY' is invalid or missing\"],\"errorName\":\"Exception\",\"success\":false,\"totalCount\":1,\"vmid\":\"331004\",\"errorMessageText\":[\"API ACCESS DENIED!!! Api Key 'VIATOR_API_KEY' is invalid or missing\"]}", :debug_info=>#<Ethon::Easy::DebugInfo:0x007fd463988ca0 @messages=[]>}, @request=#<Typhoeus::Request:0x007fd464810f98 @base_url="https://viatorapi.viator.com/service/search/products", @original_options={:method=>:post, :params=>{:apiKey=>"VIATOR_API_KEY"}, :body=>{:destId=>684}, :headers=>{"Content-Type"=>"application/json", :charset=>"UTF-8", "Cache-Control"=>"no-cache"}}, @options={:method=>:post, :params=>{:apiKey=>"VIATOR_API_KEY"}, :body=>{:destId=>684}, :headers=>{"User-Agent"=>"Typhoeus - https://github.com/typhoeus/typhoeus", "Content-Type"=>"application/json", :charset=>"UTF-8", "Cache-Control"=>"no-cache"}, :maxredirs=>50}, @response=#<Typhoeus::Response:0x007fd46396b920 ...>, @on_headers=[], @on_complete=[#<Proc:[email protected]/Users/toni/learn/ruby/stackoverflow/scripting/typhoeus_request.rb:11>], @on_success=[]>, @handled_response=nil> 
    irb(main):113:0> 

немного бит довольно

irb(main):039:0> require 'yaml' 
=> true 
irb(main):043:0> puts request.response.to_yaml 
--- &3 !ruby/object:Typhoeus::Response 
options: 
    :httpauth_avail: 0 
    :total_time: 0.6263529999999999 
    :starttransfer_time: 0.6262380000000001 
    :appconnect_time: 0.264124 
    :pretransfer_time: 0.264161 
    :connect_time: 0.131438 
    :namelookup_time: 0.00059 
    :redirect_time: 0.0 
    :effective_url: https://viatorapi.viator.com/service/search/products?apiKey=VIATOR_API_KEY 
    :primary_ip: 54.165.220.73 
    :response_code: 200 
    :request_size: 269 
    :redirect_count: 0 
    :return_code: :ok 
    :response_headers: "HTTP/1.1 200 OK\r\nDate: Fri, 29 Apr 2016 06:25:36 GMT\r\nContent-Type: 
    application/json;charset=ISO-8859-1\r\nContent-Length: 371\r\nVary: Accept-Encoding\r\n\r\n" 
    :response_body: '{"errorReference":"~2155052986177618334013969","data":null,"dateStamp":"2016-04-28T23:25:36+0000","errorType":"EXCEPTION","errorMessage":["API 
    ACCESS DENIED!!! Api Key ''VIATOR_API_KEY'' is invalid or missing"],"errorName":"Exception","success":false,"totalCount":1,"vmid":"331009","errorMessageText":["API 
    ACCESS DENIED!!! Api Key ''VIATOR_API_KEY'' is invalid or missing"]}' 
    :debug_info: !ruby/object:Ethon::Easy::DebugInfo 
    messages: [] 
request: !ruby/object:Typhoeus::Request 
    base_url: https://viatorapi.viator.com/service/search/products 
    original_options: 
    :method: :post 
    :params: &1 
     :apiKey: VIATOR_API_KEY 
    :body: &2 
     :destId: 684 
    :headers: 
     Content-Type: application/json 
     :charset: UTF-8 
     Cache-Control: no-cache 
    options: 
    :method: :post 
    :params: *1 
    :body: *2 
    :headers: 
     User-Agent: Typhoeus - https://github.com/typhoeus/typhoeus 
     Content-Type: application/json 
     :charset: UTF-8 
     Cache-Control: no-cache 
    :maxredirs: 50 
    on_complete: 
    - !ruby/object:Proc {} 
    on_headers: [] 
    response: *3 
    on_success: [] 
handled_response: 
=> nil 
0

Я не мог найти документацию по API для этого сайта, но оказывается, что конечная точка ожидает, что apiKey будет параметром запроса url и не в полезной нагрузке.

+0

Да, вы правы. Документация Api: «Ключ API должен быть добавлен к каждому вызову API в качестве параметра URL для вызовов GET и POST». Но, во всяком случае, в ruby-скрипте я отправляю запрос с apiKey по URL-адресу – Derk153

0

Если вы хотите придерживаться чистого Ruby и Net::HTTP, тогда я рекомендую requests, обертка на Net::HTTP, что делает его очень простым для отправки запросов.

Смежные вопросы