Out now! Check out the Poll results: Do you have a Shopify store?
Our Partner & Developer boards on the community are moving to a brand new home: the .dev community forums! While you can still access past discussions here, for all your future app and storefront building questions, head over to the new forums.

Storefront API GraphQL Inconsistent Results Between Postman + PHP

Storefront API GraphQL Inconsistent Results Between Postman + PHP

Richard_Peck
Shopify Partner
13 2 3

I need to filter products by the "available_for_sale" property. 

 

It works perfectly in Postman - results are consistent and exactly as I would expect.

 

However, when I attempt to recreate the query in PHP, the results are incorrect. Specifically, they include a number of products which have the wrong "available_for_sale" property.

 

I have tried many different things to rectify the issue - using a raw cURL request to graphQL, changing the query, hardcoding everything, ensuring all of the URL / payload structure is correct, but the same thing happens.

 

The query I am running is as follows: -

 

 
    {
        products(first: 250, query: "tag:[redacted] AND product_type:[redacted] AND NOT available_for_sale:true", sortKey: TITLE, reverse: true) {
            edges {
                node {
                    handle
                    title
                    availableForSale
                }
            }
        }
    }
 

This code is slightly more complicated in the production/live environment, but the issue persists regardless.

 

The above, when run in Postman, provides a payload similar to the following: 

 

postman.jpg

 

The part that is confusing me is there is nothing different between the query I've been running in Postman and the one I've ran in PHP.  Yet, the PHP request (multiple servers, using composer package and cURL) returns the same erroneous response: -

 

php.jpg

 

I have not tried it locally yet (will write a simple Ruby script in a few minutes) but I am extremely confused as to why it's working perfectly in Postman and not in my PHP scripts. Is it something I have done (or not done)?

 

Happy to share request payloads in private.

Replies 8 (8)

SBD_
Shopify Staff
1831 273 421

Hey @Richard_Peck,

 

Can you share request IDs from both the Postman request and the PHP request, or provide some PHP code (in it's simplest form) which isn't filtering correctly?

Scott | Developer Advocate @ Shopify 

Richard_Peck
Shopify Partner
13 2 3

Good morning, thank you for the reply.

 

Firstly, I've done some more investigating and it seems that the core problem is the Storefront API seems to be caching its responses. I am not sure why this is causing the available/unavailable filtering to become problematic, but I'd imagine it to be a contributing factor. Other requests are not updating as we've added new products and they are not showing.

 

The code I have been using to test is as follows: -

 

// Constants
define('SHOPIFY_API_TOKEN',   '*********************');
define('SHOPIFY_API_URL',     '*********************');
define('SHOPIFY_API_VERSION', '2023-10');
define('NUM_PRODUCTS',        250);

// Headers
header('Content-Type: application/json');
header("Access-Control-Allow-Origin: *");

///////////////////////////////
///////////////////////////////

// RPECK 05/07/2023
// Use cURL to get the GraphQL data because the Shopify API wrapper returned dodgy results
function graphQL($query, $variables = null) {

	// Vars
	$data = array();
	$data['query']     = $query;
	$data['variables'] = $variables;

	// Initialize cURL
	$curl_init = curl_init();

	// Set cURL options
	curl_setopt($curl_init, CURLOPT_URL, 'https://' . SHOPIFY_API_URL . '/api/' . SHOPIFY_API_VERSION . '/graphql.json"');
	curl_setopt($curl_init, CURLOPT_HTTPHEADER,
		array(
			'Content-Type: application/json',
			'Accept: application/json',
			'X-Shopify-Storefront-Access-Token: ' . SHOPIFY_API_TOKEN,
			'Cache-Control: no-cache'
		)
	);
	curl_setopt($curl_init, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($curl_init, CURLOPT_CUSTOMREQUEST, "POST");
	curl_setopt($curl_init, CURLOPT_POSTFIELDS, json_encode($data));
	curl_setopt($curl_init, CURLOPT_SSL_VERIFYPEER, true);

	// Response
	$response = curl_exec($curl_init);

	// Close cURL
	curl_close($curl_init);

	// Return
	return $response;
}

$query = '
	{
		products(first: 250, query: "tag:****** AND product_type:***** AND available_for_sale:true", sortKey: CREATED_AT, reverse: true) {
			edges {
				node {
					handle
					title
					availableForSale
				}
			}
		}
	}
';

$payload = graphQL($query);

echo print_r(json_decode($payload), true);
die();

 

 

This code outputs the payload I screenshotted in my initial post.

 

As you can tell from the comment, I was originally using the Shopify composer package to wrap the API but started testing with cURL once I spotted the issue.

 

Request ID's: -

  • Postman (works 100%) ce4bd46a-563b-419f-a4b0-c1236ffffd17
  • Postman (works 100%) 1f4bdce3-0e30-4b80-81b3-f3140353e5ee
  • PHP (cached) 9061a190-fdd6-433b-88ae-b1c7614b488a
  • PHP (cached) 6b260774-21e7-43be-b228-95f54494d1ec

Happy to provide further details in private if required.

 

I'm working on a workaround to this already but it would have been nice to have the fact that the Storefront API is cached mentioned in the documentation.

Richard_Peck
Shopify Partner
13 2 3

Just to briefly follow up, the cache seems to have refreshed and both issues I was seeing (incorrect filtering as mentioned here and missing products) has been resolved.

 

Thus, my question is really about how to trigger a cache refresh on the Storefront API? As it is running through Cloudflare, I suppose it's not possible from the client side?

SBD_
Shopify Staff
1831 273 421

Thanks for the details! If it's working 100% of the time in Postman it indicates there's not a problem with the Storefront API cache but instead the PHP method is caching somewhere along the way.

Scott | Developer Advocate @ Shopify 

Richard_Peck
Shopify Partner
13 2 3

If that's the case, why did these people experience exactly the same problem? 

 

https://community.shopify.com/c/hydrogen-headless-and-storefront/storefront-api-response-cached/m-p/...

SBD_
Shopify Staff
1831 273 421

Those folks are reporting `accept-language` made a different. Can you compare your Postman request to the PHP requests (including headers)?

Scott | Developer Advocate @ Shopify 

lounik
New Member
4 0 0

Hi,

 

did you figure out a way to solve this? I have the exact same problem: postman is fine but php gives wrong results

rpeck90
Shopify Partner
2 0 0

I found that the problem was due to the storefront endpoint being cached.

 

Postman use different VPS instances to send the requests, whereas I was using a single one. This explained why my requests were "stuck" and theirs weren't.

 

My solution was to switch to the admin API, which meant I had a limit on the number of objects I could pull through each time. My primary reason for using the storefront API was that it was not rate limited, which they seem to have been able to achieve due to caching it!