A space to discuss GraphQL queries, mutations, troubleshooting, throttling, and best practices.
I'm using the shipping_zones.json Admin REST API endpoint to get a list of all configured shipping zones and their rates so that I can determine the shipping cost per product variant.
This works fine for the default shipping zones, however the shop I'm working with also has custom shipping zones (I believe these are called delivery profiles now), that some products are assigned to. With the GraphQL API I can get the products that are assigned:
query deliveryProfile {
deliveryProfile(id: "gid://shopify/DeliveryProfile/123456789") {
default
profileItems(first: 250) {
edges {
node {
product {
id
}
}
}
}
}
}
However this query is quite inefficient (query cost of ~500), and allows me to get max 250 items at a time. Anyway, if I also want to get all of the profile item's variant ids, this query becomes impossible cost-wise.
So I thought I could use a bulk operation for this, but turns out that's not possible because DeliveryProfileItem has no "id" field and without it I can't write the bulk query:
{
deliveryProfiles {
edges {
node {
id
default
profileItems {
edges {
node {
// no id field exists here
product {
id
}
variants {
edges {
node {
id
}
}
}
}
}
}
}
}
}
}
The parent 'node' field for a nested connection must select the 'id' field. Connection fields without 'id': profileItems.
(see https://shopify.dev/docs/admin-api/graphql/reference/shipping-and-fulfillment/deliveryprofileitem)
TBH it seems like this is something that would be relatively straightforward if a REST API endpoint was exposed for this, but the GraphQL API makes it pretty expensive to do this. So now I'm wondering how to solve this... is it actually something that could be considered a bug, that the DeliveryProfileItem node id is not exposed?
Solved! Go to the solution
This is an accepted solution.
This has actually been fixed, at least in API version 2022-04. The profile item id is now available.
Hey, did you find a solution to this? Or did you go with another approach?
Sorry for the late reply. I did find a temporary work-around.
First I get the shipping zones using the REST API.
const res = await fetch(`https://${shop}/admin/api/${SHOPIFY_API_VERSION}/shipping_zones.json`, {
method: 'GET',
headers: { 'X-Shopify-Access-Token': accessToken },
});
const { shipping_zones } = await res.json();
Then I retrieve the delivery profile id from each zone (except the first one which is the default zone, not a custom one, but can't really recall why I'm skipping it in my case).
const customDeliveryProfileIds = Array.from(new Set(shipping_zones.map(zone => zone.profile_id))).slice(1);
Then I pass those profile ids into a GraphQL query.
const { data } = await apolloClient.query({
query: gql`
query deliveryProfiles($profileIds: [ID!]!) {
nodes(ids: $profileIds) {
... on DeliveryProfile {
id
profileItems(first: 250) {
edges {
node {
product {
id
}
}
}
}
}
}
}
`,
variables: { profileIds: customDeliveryProfileIds },
});
I guess the trick is to use the `nodes` query with a specific list of ids (the number of ids you query doesn't actually increase the query cost). However there's still the limitation that it only gets the first 250 products of each delivery profile 😕
It's ok for now but I'm waiting for a resolution of this so I can do the bulk query.
This is an accepted solution.
This has actually been fixed, at least in API version 2022-04. The profile item id is now available.