_NB: Tolong beri tahu saya jika ini termasuk dalam faraday_middleware
. Karena melibatkan dua middleware, saya tidak tahu harus meletakkannya di mana._
Saat membuat koneksi, saya berharap (seperti yang didokumentasikan) middleware akan berjalan sesuai urutan yang dideklarasikan. Namun, ketika permintaan gagal dan saya memuat middleware parsing :json
diikuti oleh middleware :retry
, env.body
tidak diuraikan dalam lingkup :retry
middleware :retry_if
blok:
Saya perlu menjalankan blok :retry_if
pada JSON
-pesan yang didekodekan karena dokumen JSON bisa sangat besar jika permintaan berhasil, dan alternatifnya adalah menguraikannya untuk kedua kalinya di retry_if
, yang tampaknya sama sekali tidak perlu.
<strong i="23">@_client</strong> ||= Faraday.new(url: ROOT_URL) do |f|
f.options[:timeout] = 10
f.headers['Content-Type'] = 'application/json'
f.use :instrumentation, name: INSTRUMENTATION_EVENT_NAME
f.response :json, content_type: /\bjson$/
f.request :retry, FARADAY_RETRY_OPTIONS
end
Catatan: Jika saya mencetak f.instance_variable_get :@handlers
, di dalam blok, saya melihat middleware dalam urutan yang saya nyatakan.
Ketika permintaan gagal, dan saya mengevaluasi ekspresi ini di blok :retry
middleware :retry_if
middleware, saya mendapatkan output berikut:
(byebug) environment.response.to_hash.without(:url)
{:status=>405, :body=>"{\"message\": \"The method is not allowed for the requested URL.\"}\n", :response_headers=>{"date"=>"Fri, 23 Apr 2021 18:17:16 GMT", "content-type"=>"application/json", "content-length"=>"64", "connection"=>"keep-alive", "server"=>"gunicorn", "allow"=>"HEAD, OPTIONS, GET"}}
(byebug) environment.response.body
"{\"message\": \"The method is not allowed for the requested URL.\"}\n"
(byebug) environment.response.body.class
String
Pada dasarnya, parsing middleware hanya menolak untuk dijalankan terlebih dahulu.
JSON dibentuk dengan baik dan header Content-Type
respons disetel dengan benar, jadi saya bingung.
Satu-satunya tebakan saya adalah itu ada hubungannya dengan #response
middleware selalu berjalan sebelum #request
middleware, tetapi dalam kasus ini retry
menjadi #request
middleware adalah sesuatu yang keliru karena secara implisit perlu dievaluasi setelah respon dikembalikan.
Pembaruan: Saya benar-benar membalik urutan dua middlewares di blok konfigurasi koneksi (sambil berpikir "ini tidak mungkin berfungsi") dan sekarang berfungsi dengan sempurna. Meninggalkan ini karena saya tidak tahu apa yang terjadi dan sepertinya masih seperti bug (atau setidaknya harus didokumentasikan dengan lebih baik).
Hai @mvastola , apa yang Anda alami adalah perilaku yang diharapkan!
Saya tahu sulit untuk memahaminya pada awalnya, tetapi mengingat sifat tumpukan middleware yang mirip dengan tumpukan rak, middleware dilintasi dalam urutan terbalik untuk tanggapan.
Di situs web kami, kami memiliki gambar yang menggambarkan hal ini agar lebih mudah dipahami.
Karenanya Anda sudah melakukan hal yang benar ! Dengan memindahkan :json
middleware setelah :retry
, Anda mengizinkan respons diproses oleh middleware itu terlebih dahulu, dan middleware :retry
akan menemukan isi respons diuraikan.
Saya menutup ini sekarang tetapi jangan ragu untuk menindaklanjuti jika Anda memiliki pertanyaan lebih lanjut
Terima kasih atas penjelasannya yang cepat, baik, dan menyeluruh. Ini tidak terlalu sulit untuk dipahami, tetapi agak tidak intuitif di sini. Saya ingin tahu apakah ada cara yang efektif untuk menguranginya.
Saya sebenarnya telah melihat dokumentasi yang Anda tautkan, dan itu membuat saya berpikir bahwa saya tahu apa yang harus saya lakukan. (Saya melihat gambarnya, dan hal-hal tentang middleware "terdalam", tetapi saya tidak benar-benar memproses bahwa itu berarti membalik urutannya.)
Gambar yang ditampilkan informatif mengenai bagian dalam middleware, tetapi mungkin berguna untuk melengkapinya dengan indikasi visual tentang bagaimana urutan di blok konfigurasi memengaruhi urutan yang dijalankan.
Di luar itu, ada banyak detail implementasi ini yang membuat ini tidak intuitif:
Ada tiga fungsi yang berbeda di faraday
untuk menambahkan middleware, dan mereka tidak dapat dipertukarkan: setiap bagian dari middleware tampaknya hanya bekerja dengan salah satunya. Ini membuatnya tampak seolah-olah ada tiga tumpukan (atau urutan) Middleware berbeda yang independen satu sama lain.
Namun, apa yang dilakukan oleh ketiga nama/grup Middleware yang berbeda ini sangat tidak jelas, karena sebagian besar Middleware _not_ berjalan di kedua ujung jalur permintaan->respons, pengguna akan cenderung menganggap tugas "permintaan" selalu terjadi sebelum "respons" hal-hal yang terkait.
Kata kunci rak untuk menambahkan middleware, use
, berlaku (sebaik yang saya tahu) di Faraday hanya untuk middleware semacam itu -- middleware yang membungkus permintaan dan respons.
Bagaimanapun saya senang mencoba memikirkan beberapa ide jika Anda terbuka untuk mengubah API untuk masalah ini. Kalau tidak, setidaknya saya mendapatkan ini sekarang. Saya hanya mengatakan ini karena saya dapat dengan mudah melihat pengguna lain mengalami kebingungan yang sama di sini.
Terima kasih @mvastola , ini adalah umpan balik yang sangat berharga 🙏!
Dan sejujurnya, ini bukan pertama kalinya saya mendengar tentang hal ini.
Ketika datang ke dokumentasi, saya setuju kita masih jauh, jadi kontribusi apa pun untuk meningkatkan itu sangat disambut (sebenarnya ada utas diskusi yang sangat baru tentang itu!).
Poin-poin pada konfigurasi juga sangat valid, izinkan saya mengatakan bahwa kebingungan metode request
, response
dan use
telah dimunculkan beberapa kali, sampai-sampai saya sebenarnya mempertimbangkan untuk menjatuhkan mereka demi hanya memiliki use
, kemudian meninggalkan middleware untuk mendokumentasikan apa/kapan mereka akan memanipulasi permintaan/tanggapan.
Jadi saya sarankan untuk tidak mendorong PR apa pun untuk mengubah API itu dulu, tetapi kami sangat terbuka untuk mendengar komunitas tentang topik ini melalui diskusi
Komentar yang paling membantu
Hai @mvastola , apa yang Anda alami adalah perilaku yang diharapkan!
Saya tahu sulit untuk memahaminya pada awalnya, tetapi mengingat sifat tumpukan middleware yang mirip dengan tumpukan rak, middleware dilintasi dalam urutan terbalik untuk tanggapan.
Di situs web kami, kami memiliki gambar yang menggambarkan hal ini agar lebih mudah dipahami.
Karenanya Anda sudah melakukan hal yang benar ! Dengan memindahkan
:json
middleware setelah:retry
, Anda mengizinkan respons diproses oleh middleware itu terlebih dahulu, dan middleware:retry
akan menemukan isi respons diuraikan.Saya menutup ini sekarang tetapi jangan ragu untuk menindaklanjuti jika Anda memiliki pertanyaan lebih lanjut