Where is a good place to initialize an API?

Solution 1:

The answer to this question really depends on your use case and your approach. My geral recommendation, however, is to create a Service Object (in the DDD sense) (see the section named "Domain Objects Should Not Know Anything About Infrastructure Underneath" in that link), that handles all communication with the Coinbase API. And then, within this service object, you can simply initialize the Coinbase::Client object once for however many times you call into it. Here's an example:

# app/services/coinbase_service.rb
class CoinbaseService
  cattr_reader :coinbase_client, instance_accessor: false do
    Coinbase::Client.new(ENV['COINBASE_API_KEY'], ENV['COINBASE_API_SECRET'])
  end

  def self.do_something
    coinbase_client.do_something_in_their_api
  end

  def self.do_something_else
    coinbase_client.do_something_else_in_their_api
  end
end

So then you might do, e.g.:

# From MyController#action_1
if CoinbaseService.do_something
  # ...
else
  # ...
end

Or:

# From MyModel
def do_something
  CoinbaseService.do_something_else
end

To get the service object working, you may need to add app/services to your autoload paths in application.rb file. I normally just add this:

# config/application.rb
config.autoload_paths += %W(#{config.root}/app)

I find this Service Object approach to be very beneficial organizationally, more efficient (only 1 invocation of the new Coinbase client needed), easier to test (easy to mock-out calls to Coinbase::Client), and simply joyful :).

Solution 2:

One way to go about having a global variable can be done as similar as initializing redis in a Rails application by creating an initializer in config/initializers/coinbase.rb with:

$coinbase = Coinbase::Client.new(ENV['COINBASE_API_KEY'], ENV['COINBASE_API_SECRET'])

Now, you can access $coinbase anywhere in the application!