Когда мне нужны внешние сервисы для общего ответа, я использую парсер. В других языках вы могли бы использовать интерфейсы для принудительного выполнения контракта подписи метода, , но Ruby не имеет этой функции из-за утки, набирающей .
Этот парсер может быть функцией или модулем. Например:
module GitHub
class Service
BASE_URI = 'https://api.github.com'
def self.fetch
response = HTTP.get("#{BASE_URI}/clients")
raise GitHub::ApiError unless response.ok?
Parser.new(response).to_common
end
end
class Parser
def initialize(response)
@response = response
end
def to_common
json_response = JSON.parse(@response)
json_response[:customers] = json_response.delete :clients
# more rules
# ...
json_response
end
end
end
Хорошо, вот и все. Теперь у вас есть служба для извлечения и обработки части HTTP и анализатор, который обрабатывает тело ответа из HTTP-запроса. Теперь предположим, что вы хотите использовать другой API, например BitBucket API:
module BitBucket
class Service
BASE_URI = 'https://bitbucket.com/api'
def self.fetch
response = HTTP.get("#{BASE_URI}/customers")
raise BitBucket::ApiError unless response.ok?
Parser.new(response).to_common
end
end
class Parser
def initialize(response)
@response = response
end
def to_common
json_response = JSON.parse(@response)
json_response[:clients] = (json_response.delete(:data).delete(:clients))
# more rules
# ...
json_response
end
end
end
Таким образом, обе службы будут возвращаться с использованием одного и того же интерфейса. Чтобы присоединиться к результатам, вы можете сделать:
data = [GitHub::Service.fetch, BitBucket::Service.fetch, ...]
names = data.map { |customer_list| customer_list[:name] }
names.uniq