Я бы сказал, что два разных типа объектов в совокупности.
Клиенты
Это классы, которые просто выполняют HTTP-вызовы и касаются границы приложения. Причина, по которой вы хотите изолировать это в отдельном объекте, заключается в том, что он позволяет вам его высмеивать в тестах. Это также держит обязанности ясными.
# adapted from the HTTParty readme
class StackExchangeClient
include HTTParty
base_uri 'api.stackexchange.com'
def initialize(service, page)
@options = { query: { site: service, page: page } }
end
def questions
self.class.get("/2.2/questions")
end
def users
self.class.get("/2.2/users")
end
end
/lib
- довольно хорошее место для хранения клиентов, поскольку они редко должны содержать какую-либо логику, специфичную для приложения.
Сервисные объекты
Сервисные объектыПростые старые объекты Ruby (PORO), которые предназначены для выполнения одного отдельного действия в логике вашего домена и делают это хорошо.
- Объекты службы Rails: полное руководство
class QuestionImporterService
def initialize(service, page, client: nil)
@client = client || StackExchangeClient.new(service, page)
end
def call
questions = @client.get_questions
questions.map do |attributes|
Question.new(attributes)
end
end
end
В этом примере используется внедрение конструктора , чтобы позволить вам макетировать HTTP-вызовы для тестирования.
Службы можно размещать в /app/services
. Иногда Spring «зависает» и не берет новые папки в /app
для автозагрузки, в этом случае вы перезапускаете его, вызывая $ spring stop
.