Salah satu penyedia layanan yang saya gunakan memiliki URL seperti ini: https://service.com/service:search
. Inilah cara kami mengatur Faraday:
class Provider::Client
...
delegate :post, :patch, :delete, :put, to: :client
def client
Faraday.new(url: 'https://service.com/') do |faraday|
faraday.headers = headers.merge(content_type: content_type)
faraday.response(:json, content_type: CONTENT_TYPE)
faraday.basic_auth(USER, PASSWORD)
faraday.adapter(Faraday.default_adapter)
end
end
end
dan ketika saya memanggilnya
data = Provider::Client.post(
"service:search?limit=#{LIMIT}&offset=#{offset}", search_params
)
tetapi ketika saya melakukan ini dengan URL yang dimaksud, saya mendapatkan ini:
URI::InvalidURIError: query conflicts with opaque
from /Users/luiz/.rbenv/versions/2.7.1/lib/ruby/2.7.0/uri/generic.rb:832:in `query='
Saya berasumsi itu adalah sesuatu yang terkait dengan adaptor net/http karena ini adalah adaptor default jadi saya melakukan panggilan yang sama secara manual
require "uri"
require "net/http"
url = URI("https://service.com/service:search?limit=50&offset=400")
https = Net::HTTP.new(url.host, url.port);
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Accept"] = "custom_header"
request["Authorization"] = "Basic xxx="
request["Content-Type"] = "application/json"
request.body = "long_json"
response = https.request(request)
puts response.read_body
dan ini benar-benar berfungsi jadi saya curiga ada sesuatu di Faraday yang memvalidasi URL ini dengan cara yang berbeda dari net/http
Hai @luizkowalski , pengecualian berasal dari URI
dan dimunculkan di baris pertama metode query=
:
def query=(v)
return <strong i="9">@query</strong> = nil unless v
raise InvalidURIError, "query conflicts with opaque" if <strong i="10">@opaque</strong>
...
end
Faraday melakukan beberapa keajaiban internal pada url permintaan dengan memisahkan dan menggabungkannya kembali untuk membantu beberapa transformasi umum, dan saya kira pada titik tertentu itu dapat menyebabkan @opaque
disetel berkat kehadiran :
di URL.
Saya telah melacak masalah ini ke baris ini: https://github.com/lostisland/faraday/blob/c26df87b8653db4f270e3bcdc7a15bcdd2dd5cae/lib/faraday/connection.rb#L525
Menggunakan kode contoh Anda, base
akan menjadi #<URI::HTTPS https://service.com/>
dan url
akan menjadi service:search?limit=50&offset=400
.
Sekarang, cukup menarik, jika parameter kedua dari metode +
untuk URI berisi :
, sepertinya hasilnya sangat tidak terduga!
2.7.1 > url
=> "service:search?limit=50&offset=400"
2.7.1 > base
=> #<URI::HTTPS https://service.com/>
2.7.1 > base + url
=> #<URI::Generic service:search?limit=50&offset=400>
Untuk beberapa alasan, base
dihapus dan hanya url yang tersisa.
Perbaikannya cukup mudah dalam hal ini, cukup dengan menambahkan /
ke url dan semuanya berfungsi seperti yang diharapkan:
data = Provider::Client.post(
"/service:search?limit=#{LIMIT}&offset=#{offset}", search_params
)
Namun ini tidak berfungsi dalam semua kasus karena Anda mungkin perlu menambahkan jalur relatif ke base
yang tidak dapat dimulai dengan /
.
Silakan coba ini dengan menambahkan /
dan beri tahu saya jika itu berhasil, tetapi saya akan membiarkan masalah ini terbuka untuk melihat dan menemukan cara yang mungkin untuk memperbaiki baris kode itu di Faraday sehingga bekerja dalam kasus ini.
Jika Anda ingin mencobanya sendiri, saya akan dengan senang hati meninjau PR
@iMacTia berhasil sekarang. URL dasarnya adalah: https://service.com/api
. Ketika saya menambahkan /
ke service:search
saya mendapatkan kesalahan dan memperhatikan bahwa /api
hilang dari URL dasar jadi saya menambahkan /api/service:search
dan sekarang tidak masalah
@luizkowalski sempurna, ya itulah yang saya maksud dengan
Namun ini tidak berfungsi dalam semua kasus karena Anda mungkin perlu menambahkan jalur relatif ke basis yang tidak dapat dimulai dengan /.
Seperti yang diasumsikan faraday, URL yang disediakan adalah absolut jika dimulai dengan /
dan menghapus jalur yang disediakan ke pangkalan.
Senang Anda sudah menemukan solusinya, tetapi ini masih harus diperbaiki dengan benar sehingga solusi tidak diperlukan lagi
Komentar yang paling membantu
@luizkowalski sempurna, ya itulah yang saya maksud dengan
Seperti yang diasumsikan faraday, URL yang disediakan adalah absolut jika dimulai dengan
/
dan menghapus jalur yang disediakan ke pangkalan.Senang Anda sudah menemukan solusinya, tetapi ini masih harus diperbaiki dengan benar sehingga solusi tidak diperlukan lagi