简体   繁体   中英

Where would be a good place to store logic for a call to a third party api, based on Ruby on Rails best practices?

I am practicing making third-party api calls using the rest-client gem. Right now, my code for making a call to a third-party api is stored in a show method in my search_controller.rb . I'm assuming it would be better to store that logic somewhere other than a controller, in order to follow the "skinny controller" practice of ruby on rails. Where would be a better place to put this type of logic, or is this an ok place to have it?

I would say two different kinds of objects in conjunction.

Clients

These are classes that simply do HTTP calls and touch the application boundary. The reason you want to isolate this in a discrete object is that it allows you mock it in tests. It also keeps the responsibilities clear.

# 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 is a pretty good place to store clients since they rarely should contain any application specific logic.

Service objects

Service objects are Plain Old Ruby Objects (PORO) that are designed to execute one single action in your domain logic and do it well.
-- Rails Service Objects: A Comprehensive Guide

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

This example uses constructor injection to allow you to mock out the HTTP calls for testing.

You can place services in /app/services . Sometimes Spring gets "stuck" and does not pickup new folders in /app for autoloading in which case you restart it by calling $ spring stop .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM