Reputation: 95
I'm using the Twitter gem and Devise/Omniauth to perform actions on a user's behalf. Everything is going smoothly and I can successfully tweet for folks. However, something feels icky.
How are you guys persisting the Twitter client? I.e.
client = Twitter::REST::Client.new do |config|
config.consumer_key = Rails.application.secrets.twitter_consumer_key
config.consumer_secret = Rails.application.secrets.twitter_consumer_secret
config.access_token = 'xxxx'
config.access_token_secret = 'xxxx'
end
It doesn't make sense in my brain to instantiate the client before every subsequent API call. Twitter, as you know, will rate limit you after a while.
So, what's the best way to persist 'client' throughout a session?
Upvotes: 0
Views: 265
Reputation: 761
While initialising Twitter client in initializer its better to not include the access token and the access secret token in the initializer since this value will vary from user to user .And when initialising it to any local /instance variables try to use TWITTERCLIENT.dup because it will create a different object ID for your instance,if you will use the same constant then any change to the instance variables will be affect the constant .
Upvotes: 0
Reputation: 7532
Actually, instantiating the client 100 times doesn't involve any more communication with Twitter than instantiating it once; it's the actual use of the client that invokes the network traffic and thus matters. But, you're not wrong that there's no real reason to re-instantiate it each time. You have a couple options, depending on your use case:
config/initializers/twitter.rb
and assign it to something globally-accessible, like a constant (TwitterClient = Twitter::REST::Client.new do ...
). This is only okay if your configuration is never changed unless you redeploy the app, and -- importantly -- if the Twitter client is thread-safe. That's often not a valid assumption for Ruby gems, but if you're running on MRI, you probably don't need to worry about it.Inside whatever object you use the twitter client, cache the instance. The easiest way to do this is like so:
def twitter_client
@twitter_client ||= Twitter::REST::Client.new do ...
end
# ...
def other_method
twitter_client.do_something(foo: "bar")
end
However, your mileage may vary -- instance-variable caching only sticks around as long as the object does, which for a controller is only during one request. You could also cache it into a class variable, but that's effectively the same as the first option, above.
Ultimately, instantiating Ruby objects is pretty cheap, so I wouldn't worry too much about it. Trying to avoid instantiating objects often ends you up wasting more of your time in development than you'll actually save in production (as with most premature optimizations).
Upvotes: 1