Errno :: EADDRNOTAVAIL al enviar una solicitud a api desde Rails en Docker

Aug 15 2020

Lo que quiero hacer

Quiero obtener la respuesta de la información del libro pulsando la API de Google Books desde el modelo de libro de Rails.

El error que ocurrió

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'

código

Acceda a la API utilizando las palabras clave (nombre del libro, autor, etc.) enviadas desde el formulario.

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

Dado que contiene caracteres que no son ASCII, se codifica mediante el url_encodemétodo.

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

La ejecución del comando curl para el mismo punto final, por supuesto, dará la respuesta adecuada.

¿Hay algo que ver con el uso de Docker? Está basado en alpine linux.https://hub.docker.com/layers/ruby/library/ruby/2.6.6-alpine/images/sha256-95d5b6bf7084a6a0f04b48a7fc1c533ccb15e1550c670ff589ef56e620f40286?context=explore

Medio ambiente

  • Docker 2.3.0.4
  • docker-compose 3.8
  • rieles contenedor base imagen ruby: 2.6.6-alpine
  • rubí 2.6.6
  • rieles 6.0.3.2

Le agradecería que me enseñara si tiene alguna idea.
Gracias por su cooperación.

Respuestas

1 Tatsuro Aug 16 2020 at 07:03

resuelto.

La causa es

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

Cuando la cadena de caracteres devuelta cuando se codificó en esta parte se pasó a URI.parse como estaba, se devolvió URI :: Generic. Parece que el host y el esquema uri son nulos y no se pudieron adquirir correctamente. Dado que se pasa a Net :: HTTP.get tal como está, se produjo el error como el título.

URI.encodeestá en desuso, así que quería codificarlo con otro método. Finalmente, cuando se realizó URI.parse en la cadena de caracteres codificada usando WEBrick::HTTPUtils.#escape, se devolvió una instancia de URI :: HTTP, y el esquema, etc. se configuró correctamente y se resolvió.

Muchas gracias.

referencia

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