Public Shopify apps have to regularly sync data from multiple stores at a time. For example, your app might allow a customer to have multiple stores under one account (e.g. public store, wholesale store, staging store) or you could need to do this to keep your app's data updated (e.g. pulling product data to refresh your copy).
Whatever the case may be, there is a really efficient way to sync data from multiple Shopify stores.
But first...
The inefficient way
Your first impulse might be to use a loop and just iterate over every store. This might work when the number of shops are small but as the number increases, you're at risk.
If there is an error in your code or in the Shopify API, your entire loop could break. This causes a common bug where later shops are skipped over.
# WARNING: this is a baaaad idea! Shop.all.each do |shop| shop.orders = ShopifyAPI::Order.all shop.save end
The efficient way
The better solution is to perform each update in the background, using a queue like Rails' ActiveJob
.
When you do this, you can also make sure to setup a new API session. That way you know for sure that you won't have any cross-shop data contamination. In Ruby on Rails this would look like:
# In your app code or a rake task Shop.all.each do |shop| OrderSyncJob.perform_later(shop_id: shop.id) end
Job class, based on whatever queue system you use. (ActiveJob is shown here)
class OrderSyncJob < ActiveJob::Base
def perform(shop_id) shop = Shop.find(shop_id) shop.with_shopify_session do # New API session shop.orders = ShopifyAPI::Order.all end shop.save end
end
Better performance
This way you can control how fast the data is synced just by managing your queue.
Need to process everything twice as fast? Double the number of queue workers.
This job isn't that important and can be done whenever? Change your queue to prioritize these jobs lower.
Better exception handling
If there is a failure, you'll be able to track down exactly what shop had the error. You'll have a failed job sitting in your queue with the Shop details right there. You won't have to worry about re-running everything, just that one shop.
Some queues will even automatically retry the job, which is great when the error is a temporary error on Shopify's side.
Better data isolation
This also means each shop's API calls are isolated and won't affect each other. You won't be saving Big Shrimp Co's products into Veggies For You's store.
(This also helps with the API limits since they are based on the App+Shop combination)
Whenever you need to sync data from multiple Shopify shops, take advantage of your queue to isolate each shop into multiple jobs. There's nothing wrong with starting 1,000s of jobs if each one is isolated and runs within the time you need.