Faraday: Rety Middleware tidak akan berjalan setelah parser

Dibuat pada 23 Apr 2021  ·  4Komentar  ·  Sumber: lostisland/faraday

Info dasar

  • Versi Faraday: 1.4.1
  • Versi Ruby: 2.7.2

Deskripsi masalah

_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.

Langkah-langkah untuk mereproduksi

<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.

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

Semua 4 komentar

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.

Dokumen

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.

Konfigurasi

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

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

mokolabs picture mokolabs  ·  3Komentar

Lewiscowles1986 picture Lewiscowles1986  ·  4Komentar

ryanbyon picture ryanbyon  ·  3Komentar

JasonBarnabe picture JasonBarnabe  ·  4Komentar

olleolleolle picture olleolleolle  ·  5Komentar