Search code examples
javascriptnode.jscallbackshopifythrottling

How to handle Shopify's API call limit using microapps Node.js module


I have been banging my head finding an answer for this I just cant figure out. I am using a Node.js module for the Shopify API by microapps. I have a JSON object containing a list of product id's and skus that I need to update so I looping through the file and calling a function that calls the api. Shopify's API limits calls to it and sends a response header with the value remaining. This node modules provides an object containing the limits and usage. My question is based on the code below how to can at a setTimeout or similar when I am reaching the limit. Once you make your first call it will return the limits object like this:

{
 remaining: 30,
 current: 10,
 max: 40
}

Here is what I have without respecting the limits as everything I tried fails:

const products = JSON.parse(fs.readFileSync('./skus.json','utf8'));

for(var i = 0;i < products.length; i++) {
  updateProduct(products[i]);
} 

function updateProduct(product){
    shopify.productVariant.update(variant.id, { sku: variant.sku })
    .then(result => cb(shopify.callLimits.remaining))
    .catch(err => console.error(err.statusMessage));
} 

I know I need to implement some sort of callback to check if the remaining usage is low and then wait a few seconds before calling again. Any help would be greatly appreciated.


Solution

  • I would use something to limit the execution rate of the function used by shopify-api-node (Shopify.prototype.request) to create the request, for example https://github.com/lpinca/valvelet.

    The code below is not tested but should work. It should respect the limit of 2 calls per second.

    var Shopify = require('shopify-api-node');
    var valvelet = require('valvelet');
    
    var products = require('./skus');
    
    var shopify = new Shopify({
      shopName: 'your-shop-name',
      apiKey: 'your-api-key',
      password: 'your-app-password'
    });
    
    // Prevent the private shopify.request method from being called more than twice per second.
    shopify.request = valvelet(shopify.request, 2, 1000);
    
    var promises = products.map(function (product) {
      return shopify.productVariant.update(product.id, { sku: product.sku });
    });
    
    Promise.all(promises).then(function (values) {
      // Do something with the responses.
    }).catch(function (err) {
      console.error(err.stack);
    });