Приложение Rails с Faraday: проблема рефакторинга Faraday :: new () без параметра url - PullRequest
0 голосов
/ 20 июня 2020

Я занимаюсь рефакторингом кода в приложении Rails, состоящем из нескольких микросервисов. Камень faraday_middleware используется для связи между службами.

Мне удалось заменить несколько вызовов Faraday::new() в разных вспомогательных файлах одним единственным вызовом Faraday::new() в модуле ServiceConnectionHelper. У всех этих замененных вызовов был параметр url: Faraday.new(url: url)

Но остались два очень похожих фрагмента кода, от которых я хотел бы избавиться. В этих случаях параметр url отсутствует. Это старый (рабочий) код:

# This code calls the connection function below
def create(resource)
  params = {
    resource_id: resource.to_param,
    version: resource.version,
    file: Faraday::UploadIO.new(resource.file.path, resource.mime_type.to_s, resource.file.original_filename)
  }

  res = connection(resource.authorization).post(foobar_url, params)
  return res.body['id'] if [200, 201].include?(res.status)
  raise UploadError, res.body['error']
end

# connection function
def connection(authorization_header = nil)
  Faraday.new do |conn|
    conn.use FaradayMiddleware::FollowRedirects, limit: 5
    conn.request :multipart
    conn.request :url_encoded
    conn.use FaradayMiddleware::ParseJson, content_type: 'application/json'
    conn.adapter Faraday.default_adapter
    conn.headers['Accept'] = 'application/json'
    conn.headers['Authorization'] = authorization_header unless authorization_header.nil?
  end
end

Это код, который я хочу использовать вместо него. Не работает из-за ошибки внутри функции create. Когда я ловлю его и регистрирую, e.inspect это просто #<UploadError: Please specify a file>

# Small change only: Te other service's url is computed in the ServiceConnectionHelper module
def create(resource)
  params = {
    resource_id: resource.to_param,
    version: resource.version,
    file: Faraday::UploadIO.new(resource.file.path, resource.mime_type.to_s, resource.file.original_filename)
        }

  # This is were the error happens
  res = connection(resource.authorization).post('/', params)
  return res.body['id'] if [200, 201].include?(res.status)
  raise UploadError, res.body['error']
end

# connection function calls the new helper module now
def connection(authorization_header = nil)
  ServiceConnectionHelper.connection('foobar', authorization_header)
end

# the new module
module ServiceConnectionHelper
  class << self
    def connection(service, oauth_token = nil)

      url = service_url(service)

      Faraday.new(url: url) do |conn|
        conn.use FaradayMiddleware::FollowRedirects, limit: 5
        conn.request :url_encoded
        conn.adapter Faraday.default_adapter
        conn.request :multipart
        conn.use FaradayMiddleware::ParseJson, content_type: 'application/json'
        conn.headers['Accept'] = 'application/json'

        conn.headers['Authorization'] = oauth_token if oauth_token
      end
    end

    private

    def service_url(service)
      url = case service
      when 'foobar' then 'foobar_url_as_a_string'
      # the same for other services  
      end

      url
    end
  end
end

Что я могу сделать, чтобы ServiceConnectionHelper работал в этом случае?

1 Ответ

1 голос
/ 20 июня 2020

По сравнению с вашим первым примером, порядок request изменен:

conn.request :url_encoded
conn.request :multipart
...