Managing Shopify API session connections efficiently with Ruby gem

Hey everyone! I’m working with the Shopify Ruby gem for my application and need some advice on managing API sessions properly.

Since I’m using webhooks and background jobs, I need to establish connections outside of controllers. I created this helper in my Store model:

def establish_api_connection
  api_session = ShopifyAPI::Session.new(self.domain, self.token)
  api_session.valid?
  ShopifyAPI::Base.activate_session(api_session)
end

This works great for simple cases:

Store.find(1).establish_api_connection
ShopifyAPI::Shop.current.name

But here’s my issue. In my Item model, I have multiple methods that need API access, and I keep calling the connection method repeatedly. I’m concerned about creating unnecessary authentication requests.

For example, in my Item class:

class Item < ActiveRecord::Base
  belongs_to :store

  def fetch_from_api
    self.store.establish_api_connection
    @api_item = ShopifyAPI::Product.find(self.external_id)
  end

  def append_label(label_name)
    @api_item = self.fetch_from_api
    current_labels = @api_item.tags.split(",").map(&:strip)
    
    unless current_labels.include?(label_name)
      current_labels << label_name
      @api_item.tags = current_labels.join(",")
      @api_item.save
    end
  end

  def has_discount?
    @api_item = self.fetch_from_api
    discount_found = false
    
    @api_item.variants.each do |variant|
      if variant.compare_at_price && variant.compare_at_price > variant.price
        discount_found = true
        break
      end
    end
    
    discount_found
  end

  def mark_discounted_items
    self.append_label("discounted") if self.has_discount?
  end
end

When I run item.mark_discounted_items, it authenticates multiple times unnecessarily. How can I check if a session is already active before creating a new one? What’s the best way to refactor this pattern?

The problem is you’re hitting the API multiple times in the same operation. I’ve run into this before - a session validation pattern fixes it nicely. Just modify your establish_api_connection method to check if the current session matches your store’s domain before spinning up a new one. For the Item model, lazy load the API product. Store it in an instance variable on first fetch, then reuse it for other method calls in the same request. Use something like @api_item ||= fetch_api_product. Your mark_discounted_items method is also hitting fetch_from_api twice - once through has_discount? and again through append_label. Fetch once and pass the result to both operations instead. This cut my API calls way down in webhook processors.

check out ShopifyAPI::Base.current_session - it returns nil if there’s no active session. update your helper to check this first. also, think about caching the api product object in an instance var so you’re not fetching it multiple times per request.

I hit the same issue with bulk operations in background workers. The problem isn’t just session validity - the Shopify gem loses session state between method calls even when the session looks active. I fixed it with a session wrapper that validates sessions and ensures they’re scoped to the store domain. Try checking ShopifyAPI::Base.current_session&.domain == self.domain before connecting. But honestly, the bigger problem is you’re fetching the API repeatedly. Restructure your Item methods to accept the API product as a parameter instead of fetching internally. Fetch once in mark_discounted_items and pass the result to both has_discount? and append_label methods. Also watch out for concurrent background jobs messing with each other’s sessions if you’re not handling thread safety.

your establish_api_connection method calls valid? but ignores the result. wrap it in a condition that checks if the current session domain matches before creating a new one. also, pull the api fetch logic out of individual methods and create a single load_api_product method that memoizes the result.