Storefront API GraphQL Inconsistent Results Between Postman + PHP

Richard_Peck
Shopify Partner
10 1 1

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 6 (6)
SBD_
Shopify Staff
Shopify Staff
1602 227 334

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
10 1 1

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
10 1 1

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
Shopify Staff
1602 227 334

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
10 1 1

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
Shopify Staff
1602 227 334

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