Errno :: EADDRNOTAVAIL ao enviar uma solicitação para api do Rails no Docker

Aug 15 2020

O que eu quero fazer

Quero obter a resposta das informações do livro acessando a API de livros do google em Book model of Rails

O erro que ocorreu

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

Acesse a API usando as palavras-chave (nome do livro, autor, etc.) enviadas do formulário.

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

Uma vez que contém caracteres não ASCII, é codificado usando o 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

A execução do comando curl para o mesmo endpoint certamente dará a resposta adequada.

Existe algo a ver com o uso do docker? Ele é baseado no Linux alpino.https://hub.docker.com/layers/ruby/library/ruby/2.6.6-alpine/images/sha256-95d5b6bf7084a6a0f04b48a7fc1c533ccb15e1550c670ff589ef56e620f40286?context=explore

Meio Ambiente

  • docker 2.3.0.4
  • docker-compose 3.8
  • Rails container base image ruby: 2.6.6-alpine
  • rubi 2.6.6
  • trilhos 6.0.3.2

Eu ficaria muito grato se você pudesse me ensinar, se tiver alguma ideia.
Obrigado pela sua cooperação.

Respostas

1 Tatsuro Aug 16 2020 at 07:03

resolvido.

A causa é

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

Quando a cadeia de caracteres retornada quando codificada nesta parte foi passada para URI.parse como estava, URI :: Generic foi retornado. Parece que o host e o esquema uri são nulos e não podem ser adquiridos corretamente. Como é transmitido para Net :: HTTP.get como está, ocorreu um erro como o título.

URI.encodeestá obsoleto, então eu queria codificá-lo com outro método. Finalmente, quando URI.parse foi executado na string de caracteres codificada usando WEBrick::HTTPUtils.#escape, uma instância de URI :: HTTP foi retornada e o esquema etc. foi configurado corretamente e foi resolvido.

Muito obrigado.

referência

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