A space to discuss GraphQL queries, mutations, troubleshooting, throttling, and best practices.
I am migrating some code from REST to GraphQL.
The REST API code queries inventory levels and uses the updated_at filter to find only levels which have changed since last time, and it is specific to a specific location
That is, it uses
url = self.shop_url + f"/inventory_levels.json" with the parameter 'updated_at_min' and "location_ids"
I have code which gets inventory levels by a query on inventoryItems : a fragment of my query (composed in python) is:
query($cursor: String) {{
inventoryItems(first: 250, after: $cursor) {{
edges {{
node {{
id
tracked
sku
inventoryLevel(locationId: "{location_filter}") {{
id
updatedAt
quantities(names:["available"]) {{
quantity
name
but I can't use updated_at with inventoryLevel here, and it visits every inventory item with no location filter.
This is way too slow.
What should I do?
Hi @Tim_Richardson,
Like you mentioned there doesn't seem to be an GraphQL query that lets you filter inventory levels directly, you need to get there through the InventoryItem relationship. Having an inventoryLevels (similar to inventoryItems) GraphQL query would be helpful for us too.
I'm not sure of a perfect solution but here's two ideas I had (and one I tested that didn't work):
Bulk operations
One option would be running a bulk operation to export all the inventory levels at once. In short, you would:
Then locally you could parse that filter and identify the inventory levels you need changed. You'd have to benchmark it to get an exact idea of how long it'd take but generally it should be faster than looping through all the data. One limitation though is that you can only have a single bulk operation running per store at a time.
Tracking updates with webhooks
One thing I tried that didn't work was to see if InventoryItem.updated_at changes when a linked inventory level changes. It wouldn't be perfect but you could filter out some of the InventoryItems that way. Unfortunately InventoryItem.updated_at doesn't change when an associated inventory level is updated. Just including this here to save any one time if they had the same thought.
Like I mentioned, I don't know of a perfect solution but I hope this helps some. Best,
Daniel
Thanks for your reply. I also weighed up both of those options. Webhooks will be transactionally heavy I fear, but could potentially be interesting as a solution. It would be the solution with the least latency, which is very attractive.
I started coding a bulk query solution, since I figured I may as well learn about it. But it also seems like overkill for this. And the risk of getting stuck behind another job is not a risk I can take for this requirement.
However, in the short term I will do a hybrid: I will keep using the REST API for inventory levels, since it is much faster and very simple (I already have the code so I can't be any worse off by continuing to use it), and use graphql for updating stock (where it is the REST API which is stupidly inefficient, as far as I know how to use it). There is no notification of deprecation for this REST endpoint.
This is a big gap in the GraphQL API, in my opinion. So big I couldn't believe it, I thought I was doing something wrong, but you have confirmed it. Thanks for your thoughtful answer.
Yeah, the GraphQL APIs for updating a bunch of inventory at once are really nice. A lot more efficient than doing them one by one with the REST API.
I didn't realize that the REST InventoryLevel APIs don't have the API deprecation header set in the responses, that's good to know, thanks! My guess is eventually they'll be deprecated in favor of GraphQL but that buys you a good bit more time (for example, if they announce the upcoming deprecation next year it'll probably be a year after that when it actually gets deprecated)
Hi ,there
For use updated_ad as filter you could refer to this .
query GetInventoryItems {
inventoryItems(first: 10, query: "updated_at:>'2024-08-01T00:00:00+00:00'") {
edges {
node {
id
sku
updatedAt
inventoryLevel(locationId: "gid://shopify/Location/xxx") {
id
}
}
}
}
}
Ah yes, but does an inventory level change cause a change in the inventoryItem updated_at? I assumed not, so it doesn't help.