Einer der Dienstanbieter, die ich verwende, hat URLs wie diese: https://service.com/service:search
. So richten wir Faraday ein:
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
und wenn ich es aufrufe
data = Provider::Client.post(
"service:search?limit=#{LIMIT}&offset=#{offset}", search_params
)
aber wenn ich dies mit der fraglichen URL mache, erhalte ich Folgendes:
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='
Ich gehe davon aus, dass es etwas mit dem Net/HTTP-Adapter zu tun hat, da es der Standardadapter ist, also habe ich den gleichen Aufruf manuell durchgeführt
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
und das funktioniert tatsächlich, also vermute ich, dass etwas in Faraday diese URL auf eine andere Weise als net/http validiert
Hallo @luizkowalski , die Ausnahme kommt von URI
und wird in den ersten Zeilen der Methode query=
ausgelöst:
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 zaubert interne Magie auf die Anfrage-URL, indem es sie aufteilt und neu kombiniert, um bei einigen gängigen Transformationen zu helfen, und ich vermute, dass dies zu einem bestimmten Zeitpunkt dazu führen kann, dass @opaque
dank des Vorhandenseins von :
in der URL.
Ich habe das Problem bis zu dieser Zeile verfolgt: https://github.com/lostisland/faraday/blob/c26df87b8653db4f270e3bcdc7a15bcdd2dd5cae/lib/faraday/connection.rb#L525
In Ihrem Beispielcode wäre base
#<URI::HTTPS https://service.com/>
und url
wäre service:search?limit=50&offset=400
.
Interessanterweise scheint das Ergebnis ziemlich unerwartet zu sein, wenn der zweite Parameter der Methode +
für URI ein :
enthält!
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>
Aus irgendeinem Grund wird base
entfernt und nur die URL bleibt übrig.
Die Lösung ist in diesem Fall recht einfach, es reicht aus, der URL ein /
voranzustellen und die Dinge funktionieren wie erwartet:
data = Provider::Client.post(
"/service:search?limit=#{LIMIT}&offset=#{offset}", search_params
)
Dies funktioniert jedoch nicht in allen Fällen, da Sie möglicherweise einen relativen Pfad an base
anhängen müssen, der nicht mit /
beginnen darf.
Bitte versuchen Sie es, indem Sie /
voranstellen und lassen Sie mich wissen, ob das funktioniert, aber ich lasse dieses Problem offen, um einen Blick darauf zu werfen und eine Möglichkeit zu finden, diese Codezeile in Faraday zu reparieren, damit es funktioniert in diesem Fall.
Wenn Sie es selbst ausprobieren möchten, bewerte ich gerne eine PR 😃
@iMacTia es hat jetzt funktioniert. Die Basis-URL lautet: https://service.com/api
. Als ich /
zu service:search
hinzufügte, bekam ich einen Fehler und bemerkte, dass das /api
von der Basis-URL verschwunden war, also habe ich /api/service:search
hinzugefügt und jetzt ist es in Ordnung
@luizkowalski perfekt, ja genau das meinte ich mit
Dies funktioniert jedoch nicht in allen Fällen, da Sie möglicherweise einen relativen Pfad an die Basis anhängen müssen, der nicht mit / beginnen kann.
Faraday geht davon aus, dass die angegebene URL absolut ist, wenn sie mit /
beginnt und den Pfad zur Basis entfernt hat.
Schön, dass Sie den Workaround bereits gefunden haben, aber dieser sollte noch richtig behoben sein, damit kein Workaround mehr erforderlich ist
Hilfreichster Kommentar
@luizkowalski perfekt, ja genau das meinte ich mit
Faraday geht davon aus, dass die angegebene URL absolut ist, wenn sie mit
/
beginnt und den Pfad zur Basis entfernt hat.Schön, dass Sie den Workaround bereits gefunden haben, aber dieser sollte noch richtig behoben sein, damit kein Workaround mehr erforderlich ist