Faraday: Como usar a repetição com o método POST

Criado em 12 mar. 2018  ·  3Comentários  ·  Fonte: lostisland/faraday

Informação básica

  • Versão Faraday:
    farada (0.11.0)
    faraday_middleware (0.11.0.1)
    faraday_middleware-aws-signers-v4 (0.1.5)

  • Versão do rubi:
    ruby 2.3.0p0 (2015-12-25 revisão 53290) [x86_64-darwin15]

Descrição do problema

Eu tenho uma interface acessando alguma api, estava usando uma conexão Faraday com o método get e definindo um retry, e estava tudo funcionando bem até eu mudar meu método para postar então o retry parou de funcionar eu pesquisei um pouco então entendi que o post não é incluído em

IDEMPOTENT_METHODS = [:delete, :get, :head, :options, :put]

ref: https://github.com/lostisland/faraday/pull/437/files
e eu tenho que usar retry_if se eu quiser tentar novamente o POST mas não encontrei uma documentação do retry_if .

Então minha conexão fica assim:

    def my_connection(my_api_endpoint)
      Faraday.new(url: my_api_endpoint) do |faraday|
        faraday.request  :retry, max: 5, exceptions:
          [BadRequest, NotFound, ServerError, Faraday::Error::ConnectionFailed]
         faraday.response :logger
         faraday.adapter  Faraday.default_adapter
         faraday.options[:open_timeout] = 10
      end
    end

e chamando assim:

  res = my_connection(my_api_endpoint).post do |req|
    req.headers['Content-Type'] = 'application/json'
    req.options.timeout = 25
    req.body = body.to_json
  end

Qualquer ajuda será muito bem vinda.

Comentários muito úteis

Obrigado pelo feedback @yusefu e desculpe pelo TypeError.
Eu acho que o problema é que @connections deve ser um hash, não um array, meu mal!

<strong i="9">@connections</strong> ||= {}

De qualquer forma, fico feliz em saber que seu problema está resolvido 👍!

Todos 3 comentários

Oi @yusefu , desculpe a falta de documentação, isso é algo que estamos tentando resolver na v1.0.
Enquanto isso, deixe-me ajudar com seu problema. Basicamente o retry_if é uma opção que você pode passar exatamente como você passa max: 5, exceptions: [BadRequest, NotFound, ServerError, Faraday::Error::ConnectionFailed] . A única diferença é que retry_if deve ser uma função (um lambda ou um proc.
Se você não estiver familiarizado com eles, sugiro usar um proc , que pode ser instanciado com Proc.new { ... } ou com o Proc.new do ... end de várias linhas.

Então, se você quiser usar retry_if seu exemplo se tornaria algo como:

def my_connection(my_api_endpoint)
  # This is optional, I've added the <strong i="17">@connections</strong> memoized variable to avoid
  # re-creating the connection every time. Not sure it's applicable to your case
  # but consider it as it might improve performances
  <strong i="18">@connections</strong> ||= []
  @connections[my_api_endpoint] ||= Faraday.new(url: my_api_endpoint) do |faraday|
    faraday.request  :retry, max: 5, exceptions:
      [BadRequest, NotFound, ServerError, Faraday::Error::ConnectionFailed],
      retry_if: Proc.new do |env, exception|
        # your implementation goes here...
      end
     faraday.response :logger
     faraday.adapter  Faraday.default_adapter
     faraday.options[:open_timeout] = 10
  end
end

No entanto, se o seu único objetivo é adicionar :post à lista de métodos de repetição, você também pode usar a opção methods adicionada no PR que você vinculou:

def my_connection(my_api_endpoint)
  # This is optional, I've added the <strong i="23">@connections</strong> memoized variable to avoid
  # re-creating the connection every time. Not sure it's applicable to your case
  # but consider it as it might improve performances
  <strong i="24">@connections</strong> ||= []
  @connections[my_api_endpoint] ||= Faraday.new(url: my_api_endpoint) do |faraday|
    faraday.request  :retry, max: 5, exceptions:
      [BadRequest, NotFound, ServerError, Faraday::Error::ConnectionFailed],
      methods: Faraday::Request::Retry::IDEMPOTENT_METHODS + [:post]
     faraday.response :logger
     faraday.adapter  Faraday.default_adapter
     faraday.options[:open_timeout] = 10
  end
end

Por favor, deixe-me saber se isso ajuda 😄

A instância de conexões deu um TypeError.

expected MyAPI::BadRequest, got #<TypeError: {:req=>{}, :res=>nil, :headers=>nil, :reason_phrase=>nil}> with backtrace:

Mas com a simples adição de post a IDEMPOTENT_METHODS a nova tentativa agora é possível.
Muito obrigado @iMacTia 🙏 deu certo.

Obrigado pelo feedback @yusefu e desculpe pelo TypeError.
Eu acho que o problema é que @connections deve ser um hash, não um array, meu mal!

<strong i="9">@connections</strong> ||= {}

De qualquer forma, fico feliz em saber que seu problema está resolvido 👍!

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

mvastola picture mvastola  ·  4Comentários

ioquatix picture ioquatix  ·  4Comentários

mattmill30 picture mattmill30  ·  4Comentários

ryanbyon picture ryanbyon  ·  3Comentários

QuinnWilton picture QuinnWilton  ·  4Comentários