Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call External API From Ruby on Rails Controller

I am having difficulty calling an external API from my Ruby on Rails Controller

The following code is my Destinations Controller

url = URI.parse("https://api.sygictravelapi.com/1.0/en/places/list?parents=#{@destination.destination_type.downcase}:#{@destination.sygia_id}&level=poi")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true


req = Net::HTTP::Get.new(url.to_s)
req.add_field 'x-api-key', ENV["SYGIC_API_KEY"]

res = Net::HTTP.start(url.host, url.port) {
   |http|
   http.request(req)
}

The problem is that when I make this request, the response is "Bad Request", without any further information. Using the exact same request headers and URL through Postman, I get a 200-OK response from the endpoint, plus the data I expect.

When monitoring traffic using Wireshark, I see an HTTP request going to the API endpoint. But when using Postman, I see only TLS requests.

I've also tried different encoding of the Query String parameters to no avail. My assumption is that it is one of these two things that is causing the issue: 1) SSL not being used 2) QueryString Parameters not attached to the HTTP request. But would like additional eyes on my code to check I'm not missing something obvious.

like image 509
Anthony Wood Avatar asked Dec 13 '25 23:12

Anthony Wood


1 Answers

Rest-Client Ruby Gem: Help creating get request with Headers, Query, and setting a proxy

The problem turned out not to be with me but the search engine I was using. Because I live in China, I have to resort to Bing (for performance reasons)... But connecting to VPN, and with 1 Google Search I am able to find the link above.

The code below will solve the problem

body = RestClient.get "https://api.sygictravelapi.com/1.0/en/places/list?parents=#{@destination.destination_type.downcase}:#{@destination.sygia_id}&level=poi",
      headers = {accept: :json,  'x-api-key' => ENV["SYGIC_API_KEY"]}

If you don't want to install a new gem, the correct code from above is based on Postman's useful code generation feature:

require 'uri'
require 'net/http'

url = URI("https://api.sygictravelapi.com/1.0/en/places/list?parents=city%3A372&level=poi&limit=100")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["x-api-key"] = ENV["SYGIC_API_KEY"]
request["cache-control"] = 'no-cache'

response = http.request(request)
puts response.read_body
like image 154
Anthony Wood Avatar answered Dec 16 '25 17:12

Anthony Wood