Faraday: Retyミドルウェアはパーサーの後に実行されません

作成日 2021年04月23日  ·  4コメント  ·  ソース: lostisland/faraday

基本情報

  • ファラデーバージョン:1.4.1
  • Rubyバージョン:2.7.2

問題の説明

_NB:代わりにfaraday_middlewareに属するかどうか教えてください。 2つのミドルウェアが関係しているので、どこに置くかわかりませんでした。_

接続を作成するとき、(文書化されているように)ミドルウェアは宣言された順序で実行されることを期待しています。 ただし、リクエストが失敗し、 :json解析ミドルウェアに続いて:retryミドルウェアをロードすると、 env.body:retryミドルウェアの:retry_ifのスコープ内で解析されません。

JSONデコードされたメッセージに対して:retry_ifブロックを実行する必要があります。これは、リクエストが成功した場合、JSONドキュメントが非常に大きくなる可能性があるためです。別の方法として、 retry_if 2回目の解析を行います。

再現する手順

<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

注:ブロック内にf.instance_variable_get :@handlersを印刷すると、宣言した順序でミドルウェアが表示されます。

リクエストが失敗し、 :retryミドルウェアの:retry_ifブロックでこれらの式を評価すると、次の出力が得られます。

(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

基本的に、解析ミドルウェアは最初の実行を拒否するだけです。

JSONは整形式であり、応答のContent-Typeヘッダーが正しく設定されているため、困惑しています。

私の唯一の推測は、 #responseミドルウェアが常に#requestミドルウェアの前に実行されることと関係があるということですが、この場合、 retry#requestミドルウェアであることは誤称です。応答が返された後に暗黙的に評価する必要があるためです。

最も参考になるコメント

こんにちは@mvastola 、あなたが経験しているのは期待される振る舞いです!
最初は頭を悩ませるのは難しいと思いますが、ミドルウェアスタックの性質がラックスタックと似ていることを考えると、ミドルウェアは応答のために逆の順序でトラバースされます。
私たちのウェブサイトには、理解しやすくするためにこれを説明する写真があります。

したがって、あなたはすでに正しいことをしました🙌! :jsonミドルウェアを:retry :jsonミドルウェアの後に移動することで、最初に応答を処理できるようになり、 :retryミドルウェアは解析された応答本体を検出します。

終了いたしますが、ご不明な点がございましたら、お気軽にフォローアップしてください。

全てのコメント4件

更新:接続構成ブロック内の2つのミドルウェアの順序を文字通り反転しました(「これはおそらく機能しない」と考えながら)、今では完全に機能します。 何が起こっているのかわからないので、これを残しますが、それでもバグのように見えます(または少なくともより適切に文書化する必要があります)。

こんにちは@mvastola 、あなたが経験しているのは期待される振る舞いです!
最初は頭を悩ませるのは難しいと思いますが、ミドルウェアスタックの性質がラックスタックと似ていることを考えると、ミドルウェアは応答のために逆の順序でトラバースされます。
私たちのウェブサイトには、理解しやすくするためにこれを説明する写真があります。

したがって、あなたはすでに正しいことをしました🙌! :jsonミドルウェアを:retry :jsonミドルウェアの後に移動することで、最初に応答を処理できるようになり、 :retryミドルウェアは解析された応答本体を検出します。

終了いたしますが、ご不明な点がございましたら、お気軽にフォローアップしてください。

迅速、親切、そして徹底的な説明に感謝します。 理解するのはそれほど難しいことではありませんが、ここでは少し直感的ではありません。 それを減らす効果的な方法があるのだろうか。

ドキュメント

あなたがリンクしたドキュメントを実際に見たことがあり、自分が何をする必要があるかを知っていると思いました。 (私は写真と「最も内側の」ミドルウェアに関するものを見ましたが、それが順序を逆にすることを意味することを実際には処理しませんでした。)

示されているイメージは、ミドルウェアの内部に関して有益ですが、構成ブロック内の順序が実行順序にどのように影響するかを視覚的に示すことで、それを補完するのに役立つ場合があります。

構成

それを超えて、これを直感的でないものにするこの実装の詳細がたくさんあります:

  • faradayには、ミドルウェアを追加するための3つの異なる機能があり、それらを交換することはできません。ミドルウェアの各部分は、そのうちの1つでのみ機能するようです。 これにより、互いに独立した3つの異なるミドルウェアスタック(または順序)があるように見えます。

  • ミドルウェアのこれら3つの異なる名前/グループが何をするかは非常に不明確ですが、ほとんどのミドルウェアは要求->応答経路の両端で実行されないため、ユーザーは「要求」タスクが常に「応答」の前に発生すると想定する傾向があります。関連するもの。

  • ミドルウェアを追加するrackキーワードuse 、ファラデーではその種類のミドルウェア(要求と応答の両方をラップするミドルウェア)にのみ適用されます(私が知る限り)。

とにかく、この問題のAPIを微調整することにオープンであるなら、私はいくつかのアイデアを考えてみることができてうれしいです。 そうでなければ、少なくとも私は今これを手に入れます。 ここで同じ混乱に苦しんでいる他のユーザーを簡単に見ることができるので、私はこれを言っているだけです。

@mvastolaに感謝し
そして公平を期すために、私がこのことについて聞くのはこれが初めてではありません。

ドキュメンテーションに関しては、私たちが遠い道のりであることに同意するので、それを改善するための貢献は大歓迎です(実際にはそれについての非常に最近の

構成のポイントも非常に有効です。 requestresponse 、およびuseメソッドの混乱が何度も発生していると言っておきます。実際には、 useを使用するだけでそれらを削除することを検討し、ミドルウェアに任せて、要求/応答を操作する内容/時期を文書化します。
そのため、まだそのAPIを変更するためにPRをプッシュしないことをお勧めしますが、ディスカッションを通じてこのトピック

このページは役に立ちましたか?
0 / 5 - 0 評価