Tatsuro
Tatsuro

Reputation: 31

Errno::EADDRNOTAVAIL when sending a request to api from Rails on Docker

What I want to do

I want to get the response of book information by hitting google books api from Book model of Rails

The error that occurred

web_1 | Errno::EADDRNOTAVAIL (Failed to open TCP connection to :80 (Address not available-connect(2) for nil port 80)):
web_1 |
web_1 | app/models/book.rb:24:in `search'
web_1 | app/controllers/books_controller.rb:3:in `search'

code

Hit the API using the keywords (book name, author, etc.) sent from the form.

class BooksController <ApplicationController
  def search
    @results = Book.search(params[:book_search][:search_key_word])
  end
end

Since it contains non-ASCII characters, it is encoded using the url_encode method.

class Book <ApplicationRecord
  class << self
    def search(key_word)
      api_endpoint = ERB::Util.url_encode("https://www.googleapis.com/books/v1/volumes?q=#{key_word}&maxResults=20")
      response = Net::HTTP.get(URI.parse(api_endpoint)) # I'm getting the above error.
      JSON.parse(response)
    end
  end
end

Executing the curl command for the same endpoint will of course give the proper response.

Is there something to do with using docker? It is based on alpine linux. https://hub.docker.com/layers/ruby/library/ruby/2.6.6-alpine/images/sha256-95d5b6bf7084a6a0f04b48a7fc1c533ccb15e1550c670ff589ef56e620f40286?context=explore

Environment


I would be grateful if you could teach me if you have any idea.
Thank you for your cooperation.

Upvotes: 2

Views: 1276

Answers (1)

Tatsuro
Tatsuro

Reputation: 31

solved.

The cause is

ERB::Util.url_encode("https://www.googleapis.com/books/v1/volumes?q=#{key_word}&maxResults=20")

When the character string returned when encoded in this part was passed to URI.parse as it was, URI::Generic was returned. It seems that uri host and scheme are both nil and could not be acquired correctly. Since it is passed to Net::HTTP.get as it is, the error like the title occurred.

URI.encode is deprecated, so I wanted to encode it with another method. Finally, when URI.parse was performed on the character string encoded using WEBrick::HTTPUtils.#escape, an instance of URI::HTTP was returned, and the scheme etc. were set correctly and it was solved.

Thank you very much.

reference

def search(key_word)
  uri = URI.parse(WEBrick::HTTPUtils.escape("https://www.googleapis.com/books/v1/volumes?q=#{key_word}&maxResults=20"))
  response = Net::HTTP.get_response(uri)
  JSON.parse(response.body)
end

Upvotes: 1

Related Questions