Bulk operation to retrieve all inventory for a large list of product IDs

aveshopstech
Excursionist
23 0 10

Hey all,

Our app syncs inventory for our products to shops, but the target shops have products from multiple sources, not just our system. I want to periodically check the shop's inventory levels at a certain location against the stock in the source warehouse in order to update the shop, if necessary. (There are already mechanisms in place to keep inventory up-to-date in a near-real-time fashion, but every once in a while something gets out of whack.) Because we only want to check our own products on the shop, I need to query shop products based on the Product ID that we store on our side. A query to get all products and related inventory looks like this:

 

 

query($ids: [ID!]!, $locationId: ID!) {
  nodes(ids: $ids) {
    ... on Product {
      id
      variants(first: 100) {
        edges {
          node {
            id
            legacyResourceId
            inventoryItem {
              id
              legacyResourceId
              inventoryLevel(locationId: $locationId) {
                available
              }
            }
          }
        }
      }
    }
  }
}

#Query Variables:
{
    "locationId": "gid://shopify/Location/12345",
    "ids": [
        "gid://shopify/Product/12345",
        "gid://shopify/Product/12346",
        "gid://shopify/Product/12347"
    ]
}

 

 

 

However, some of these shops might have hundreds or thousands of products. Not only would a query like this take a long time, but in many cases the query would fail due to MAX_INPUT_SIZE_EXCEEDED when the `ids` array gets too big. So, there are two main problems:

1. The above query is too slow -- This problem can likely be solved with a bulk operation.

2. How do I query for a specific, LARGE list of products on a shop all at once?

Regarding speed, unfortunately the query above can't be nicely wrapped in a bulk operation. The first issue is that, according to the docs, a bulk operation query can't use the top-level `node` and `nodes` fields. Also, a maximum of only two nested connection levels can be queried. The query above breaks both of those rules. I attempted to accomplish the same goal above, but without using the root `node` field, and with a max of two nested connections. The resulting query looks like this:

 

 

query($search: String!, $locationId: ID!) {
  productVariants(first: 1000, query: $search) {
    edges {
      node {
        id
        legacyResourceId
        product {
          id
          legacyResourceId
        }
        inventoryItem {
          id
          legacyResourceId
          inventoryLevel(locationId: $locationId) {
            available
          }
        }
      }
    }
  }
}

#Query Vars
{
	"locationId": "gid://shopify/Location/12345",
	"search": "product_id:12345 OR product_id:12346 OR product_id:12347"
}

 

 

 

Once again, trouble in paradise. The query works fine up to a certain point, but once the concatenated query "search" string reaches a certain length, the returned data is empty, like this:

 

 

"data": {
  "productVariants": {
    "edges": []
  }
}

 

 

 

So... back to the drawing board. How can I get all inventory levels for a list of items for a specific location on a shop in a manner that is friendly to bulk operations? Any and all help is much appreciated!

0 Likes