graphQL api get list of products by ids or handle.

greg12
Shopify Partner
38 1 14

Hi all as in title, maybe i missed something but from what i read here https://shopify.dev/docs/admin-api/graphql/reference/common-objects/queryroot 

i can search for list of products that matches many criteria, but no for what i need. I have array of ids, or array of handles and I would like to be able to get list of products by one graphql call. Did i miss something and it is possible? 

Replies 14 (14)

Gregarican
Shopify Partner
1033 86 282

If you are managing the code that this API query is performing then it's not a ton of work to add in an iteration loop, substituting in the variable values you need for each query. It's not a single API call, but with proper respect to API rate limits it achieves what needs to be done. Pseudo-code example below in C#.

 

int[] productIds = { 1234, 5432, 6543 };
foreach (int productId in productIds)
{
    var apiCallResult = makeTheApiCall(productId);       // Make your API call and assign the result to a variable.
    doStuff(apiCallResult);                              // Do stuff with the result.
}

 

 

greg12
Shopify Partner
38 1 14

I know i can do in the loop but this pointless. If we have graphQL API then one of the goals is to get everything you need, and only what you need in one call. 

Gregarican
Shopify Partner
1033 86 282

I suppose there is a difference between what is practical and what is ideal. Usually if I'm working on a larger project I look to first and foremost do whatever it takes to get the job done. Then once the job is done I look to refactor, refine, document, and fine tune. That post-mortem work might very well include issuing a complaint about how some third-party dependency could or should work better. Which I believe is your point. 

In this case, what's practical is iterating a list or array. Not rocket science or a ton of coding really. What's ideal would be if the GQL supported natively iterating a dynamic array. To a degree you can iterate a small listing of elements in order to feed them into a GQL query. But if this is the hand we are dealt, we have to play it based on the cards.   

Gregarican
Shopify Partner
1033 86 282

Combining a handful of separate GQL queries into a single pass is possible, but likely not viable for a larger scale query that would result in a Shopify SQL query length or depth being exceeded.

Here is a Typescript project that supports this for a NodeJS environment --> https://github.com/domasx2/graphql-combine-query. Coming up with an equivalent in Ruby wouldn't be like reinventing the wheel necessarily. But again, if the concatenated query exceeds what Shopify allows for length or depth then it's a lot simpler to just code in a loop iteration and be done with it. 

HunkyBill
Shopify Expert
4843 60 546

I love how the OP claims using a loop is pointless. Such optimism about the state of computing. It's like he's already at the point where we just need think about the data we want, and boom, it'll be served up nice on a platter!

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
Gregarican
Shopify Partner
1033 86 282

A scenario similar to Microsoft's beloved Clippy reciting Matz' Principle of Least Astonishment.

dogowner
Shopify Partner
58 5 8

@greg12 I am also interested in a more efficient solution to this problem.  Were you able to find any solutions ?  In my case I am trying to query `Refund` with a list of ids corresponding to a list of orders I requested with a bulk query.

HunkyBill
Shopify Expert
4843 60 546

If you bulk download orders, you can tack on refunds. What is the problem?

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
dogowner
Shopify Partner
58 5 8

Maybe I'm doing it wrong but I actually just want the refund line items (lineItem id and restocked flag) but it seems that I can't get those with the orders.  I can only get a list of refund ids extracted from the orders.  So I want to just perform another bulk query to get those refunds.

Update: Bummer, seems that refunds can't be queried anyways so this appears to be double impossible.

HunkyBill
Shopify Expert
4843 60 546

I just did an indepth AUDIT for a merchant new to Shopify, whereby she needed to accurately assess her cost of good sold during the half year of 2020. Shopify cannot do this. So I did it, and along the way, I had to deal with orders and refunds. And stock. So I used this query, which was fine for these purposes.

NOTE: I AGREE 100%. The GraphQL and refunds is currently not consistent, and somewhat opaque, and only by lots of trial and error did I figure it out. I exposed my questions, and of course, NO ONE on these forums contributed one iota of help. Crickets do chirp.

 

mutation{
  bulkOperationRunQuery(
    query:"""
      {
        orders(query:"created_at>'2020-06-01,created_at<'2020-07-01") {
          edges {
            node {
              id
              refunds {
                id
                restocked
                refundLineItems {
                  edges {
                    node {
                      restocked
                      lineItem {
                        quantity
                        sku
                      }
                    }
                  }
                }
              }
            }
          }
          
        }
      }
    """
  ) {
    bulkOperation {
      id
      status
    }
    userErrors {
      field
      message
    }
  }
}
Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
dogowner
Shopify Partner
58 5 8

@HunkyBill 

I appreciate your reply but that query does not seem to work for me.  Maybe you have a higher plan under which it works?

I receive this error, also restocked does not seem to be a field of refund, only of refundLineItems:

'Queries that contain a connection field within a list field are not currently supported.'

Which appears to just be that you can't fetch refundLineItems, only refund fields since refunds is a list and not a connection.

HunkyBill
Shopify Expert
4843 60 546

Oh, man... ya.. my bad. I copied from Insomnia, thinking I left the query in working condition, but that was not true. It was borked, and likely due to my request I made here, in these forums, about what a mess refunds are.

From my App.. actual working code... sorry about that previous effort. You can maybe riff off this.

 

# get orders and use cursors. First call has a null cursor, result of the calls provide one
  # note the query format: "created_at:>'2020-06-01',created_at:<'2020-07-01'"
  GetOrdersWithCursor = QueryWrap.new(<<~GRAPHQL)
    query($cursor: String, $foo: String) {
      orders(first: 50, after: $cursor, query: $foo) {
        pageInfo {
          hasNextPage
        }
        edges {
          cursor
          node {
            id
            legacyResourceId
            refunds {
              refundLineItems(first: 5) {
                edges {
                  node {
                    restockType
                    lineItem {
                      sku
                      quantity
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  GRAPHQL

 

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com
dogowner
Shopify Partner
58 5 8

@HunkyBill

That query would work but I was trying to use a bulk operation query to get the orders for a batch job and it seems you can't use list fields in a bulk operation.  So that means I have to make single calls for returns and fulfillments to get the full story of an order.  I think I just have to rethink my entire strategy.  Maybe I'll start another thread about it.

dogowner
Shopify Partner
58 5 8

I had to implement throttling to make this work.  Then I just execute 2 queries for every order as necessary to get this information so worst case would be 1 query + 100 refund queries + 100 fulfillment queries.  Usually it should just be 1 query + 100 either refund or fulfillment queries.  The throttling just sleeps on and off while the data is fetched.

 

I just came back to this trying to solve the original problem in this thread.  I guess it is still not possible to get a list of resources from a list of ids with graphql.  Looks like maybe the REST API might do this.  I'll have to setup the throttling for that.