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:
-
The above query is too slow – This problem can likely be solved with a bulk operation.
-
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!