_NB: Пожалуйста, дайте мне знать, принадлежит ли это к faraday_middleware
. Поскольку он включает в себя два промежуточного программного обеспечения, я не знал, где его поставить.
При создании соединения я ожидаю (как указано в документации) промежуточное ПО будет работать в том порядке, в котором оно объявлено. Однако, когда запрос не выполняется и я загружаю промежуточное ПО для анализа :json
за которым следует промежуточное ПО :retry
, env.body
не анализируется в рамках :retry
промежуточного программного обеспечения :retry_if
блок:
Мне нужно запустить :retry_if
блока на JSON
сообщения расшифрованных , поскольку документ JSON может быть очень большим , если запрос выполнен успешно, и альтернатива , чтобы разобрать его во второй раз в retry_if
, что кажется совершенно ненужным.
<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
Middleware пакет :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
one, вы разрешаете обработку ответа этим первым, и промежуточное ПО :retry
обнаружит, что тело ответа проанализировано.
Я закрываю это сейчас, но не стесняйтесь отвечать, если у вас возникнут дополнительные вопросы.
Спасибо за быстрое, доброе и подробное объяснение. Это не так уж сложно понять, но здесь это немного не интуитивно. Интересно, есть ли эффективный способ сделать это не так.
Я действительно видел документацию, которую вы связали, и это заставило меня подумать, что я знаю, что мне нужно делать. (Я видел изображение и материал о "самом внутреннем" промежуточном программном обеспечении, но на самом деле я не осознавал, что это означает изменение порядка.)
Показанное изображение является информативным в отношении внутреннего устройства промежуточного программного обеспечения, но может быть полезно дополнить его визуальным указанием того, как порядок в блоке конфигурации влияет на порядок выполнения.
Помимо этого, есть множество деталей этой реализации, которые делают это не интуитивно понятным:
В faraday
есть три разные функции для добавления промежуточного программного обеспечения, и они не взаимозаменяемы: кажется, что каждый компонент промежуточного программного обеспечения работает только с одним из них. Это создает впечатление, что существует три разных стека (или порядка) промежуточного программного обеспечения, независимых друг от друга.
Что делают эти три разных имени / группы промежуточного программного обеспечения, очень неясно, однако, поскольку большая часть промежуточного программного обеспечения _не_ запускается на обоих концах пути запрос-> ответ, пользователь будет склонен предположить, что задачи «запрос» всегда выполняются перед «ответом». связанные вещи.
Ключевое слово стойки для добавления промежуточного программного обеспечения, use
, применяется (насколько я могу судить) в Фарадея только к этому типу промежуточного программного обеспечения - промежуточного программного обеспечения, которое охватывает как запрос, так и ответ.
В любом случае, я счастлив попытаться придумать несколько идей, если вы готовы настроить API для решения этой проблемы. В противном случае, по крайней мере, я понял это сейчас. Я говорю это только потому, что легко вижу, что другие пользователи испытывают здесь такое же замешательство.
Спасибо @mvastola , это бесценный отзыв 🙏!
И, честно говоря, я не в первый раз слышу об этом.
Что касается документации, я согласен, что до нас еще далеко, поэтому любой вклад в ее улучшение очень приветствуется (на самом деле, на эту тему есть ветка обсуждения совсем недавно!).
Пункты по настройке также очень верны, позвольте мне просто сказать, что путаница с методами request
, response
и use
возникала несколько раз, до такой степени, что я на самом деле рассматривает возможность просто отказаться от них в пользу наличия use
, оставив затем промежуточному программному обеспечению документировать, что и когда они будут манипулировать запросом / ответом.
Поэтому я бы посоветовал пока не настаивать на каких-либо пиарах, чтобы изменить этот API, но мы очень открыты, чтобы услышать мнение сообщества по этой теме в обсуждениях.
Самый полезный комментарий
Привет, @mvastola , вы испытываете ожидаемое поведение!
Я знаю, что сначала трудно понять это, но, учитывая характер стека промежуточного программного обеспечения, похожего на стэк, промежуточное программное обеспечение просматривается в обратном порядке для ответов.
На нашем веб-сайте есть изображение, которое иллюстрирует это, чтобы облегчить понимание.
Значит, ты уже поступил правильно 🙌! Перемещая промежуточное ПО
:json
после:retry
one, вы разрешаете обработку ответа этим первым, и промежуточное ПО:retry
обнаружит, что тело ответа проанализировано.Я закрываю это сейчас, но не стесняйтесь отвечать, если у вас возникнут дополнительные вопросы.