Errno :: EADDRNOTAVAIL при отправке запроса к api из Rails on Docker

Aug 15 2020

Что я хочу сделать

Я хочу получить ответ с информацией о книге, нажав google books api из книжной модели Rails

Произошедшая ошибка

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'

код

Нажмите API, используя ключевые слова (название книги, автор и т. Д.), Отправленные из формы.

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

Поскольку он содержит символы, отличные от ASCII, он кодируется с помощью этого url_encodeметода.

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

Выполнение команды curl для той же конечной точки, конечно, даст правильный ответ.

Есть какое-то отношение к использованию докеров? Он основан на alpine linux.https://hub.docker.com/layers/ruby/library/ruby/2.6.6-alpine/images/sha256-95d5b6bf7084a6a0f04b48a7fc1c533ccb15e1550c670ff589ef56e620f40286?context=explore

Окружающая обстановка

  • докер 2.3.0.4
  • docker-compose 3.8
  • рельсы контейнер базовый образ ruby: 2.6.6-alpine
  • рубин 2.6.6
  • рельсы 6.0.3.2

Буду признателен, если вы научите меня, если у вас есть идеи.
Спасибо за сотрудничество.

Ответы

1 Tatsuro Aug 16 2020 at 07:03

решено.

Причина в том

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

Когда символьная строка, возвращенная при кодировании в этой части, была передана в URI.parse как есть, возвращался URI :: Generic. Кажется, что хост и схема uri равны нулю и не могут быть получены правильно. Поскольку он передается в Net :: HTTP.get как есть, возникла ошибка, подобная заголовку.

URI.encodeустарел, поэтому я хотел закодировать его другим методом. Наконец, когда URI.parse был выполнен для строки символов, закодированной с помощью WEBrick::HTTPUtils.#escape, был возвращен экземпляр URI :: HTTP, а схема и т. Д. Были установлены правильно, и проблема была решена.

Большое спасибо.

Справка

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