Jump to content

Is GraphQL a replacement for wireHttp()?


a-ok
 Share

Recommended Posts

Hi folks. I’m a bit confused.

I built a site a year or so ago that uses `wireHttp()` to query Shopify endpoints and then would store this in the `wireCache` as well create pages on PW based on products returned etc. It was all quite simple but worked well.

Anyway. I’m looking to replace this set up with GraphQL but I’m getting super confused. Is GraphQL a replacement for wireHttp as it’s a REST replacement? Can you use GraphQL on Processwire to return third party data?

Any advice or help understanding would be really appreciated.

Link to comment
Share on other sites

So you are looking into querying data from an external service (Shopify?) that uses GraphQL?

Simply put, GraphQL is a query language: a client sends a query (defined using the GraphQL language) to the server, which then responds with a GraphQL object. WireHttp is a class you can use to send HTTP requests from ProcessWire. You could send a GraphQL request with WireHttp — so no, GraphQL is not a replacement for WireHttp 🙂

I'm not saying that you should use it, but here's a very simple GraphQL client implementation: https://gist.github.com/dunglas/05d901cb7560d2667d999875322e690a. Here's an example of querying GraphQL API with Guzzle (which, by the way, is something you could use as a replacement for WireHttp): https://dev.to/jakedohm_34/how-to-make-a-graphql-query-or-mutation-in-php-with-guzzle-359o. Or you could use something a bit more sophisticated, perhaps https://github.com/mghoneimy/php-graphql-client.

I'm not an expert on this topic, so perhaps someone with more GraphQL expertise can chime in. Just thought I'd drop some pointers 🙂

  • Like 3
Link to comment
Share on other sites

Thanks so much for this,  @teppo 🙂

Quote

So you are looking into querying data from an external service (Shopify?) that uses GraphQL?

Yep, exactly. Currently I do something like the following in ready.php  – I do something similar for products etc.

// Shopify init
$shopifyHttp = new WireHttp();
$shopifyHttp->setHeaders(['X-Shopify-Api-Features' => 'include-presentment-prices']);
$shopifyHost = "xxxxxx.myshopify.com";
$shopifyAPIKey = "xxxxxx";
$shopifyPassword = "xxxxxx";
$shopifyBase = "https://$shopifyAPIKey:$shopifyPassword@$shopifyHost/admin/";

// Get Shopify shop defaults (useful for currency checks)
wire()->addHookMethod("Page::shopifyShop", function($event) use($shopifyHttp, $shopifyBase) {
	$page = $event->object;
	// Get cache only if it's less than or equal to 1 month
	$result = wire("cache")->get("shopifyShop", WireCache::expireMonthly);
	if (!$result) {
		$result = $shopifyHttp->getJSON($shopifyBase . "shop.json");
		wire("cache")->save("shopifyShop", $result, WireCache::expireMonthly);
	}
	$event->return = $result;
});

This works great BUT the Shopify API is moving closer to GraphQL each day and feel like I should adapt, or die 😉

I'll look at those examples and see how I could change this up!

 

 

Link to comment
Share on other sites

I've been having a play... and I'm getting somewhere but passing the query itself is something I'm struggling with. I might end up using Guzzle but thought I'd see if it was possible using PW natively.

// Shopify init
$shopifyHttp = new WireHttp();
$shopifyHost = "xxxx.myshopify.com";
$shopifyPassword = "xxxx";
$shopifyHttp->setHeaders([
	'Content-Type' => 'application/json',
	'X-Shopify-Access-Token' => $shopifyPassword,
	'X-Shopify-Api-Features' => 'include-presentment-prices'
]);
$shopifyBase = "https://$shopifyHost/admin/api/2021-01/graphql.json";

$query = <<<GQL
query {
	shop {
		name
			primaryDomain {
				url
				host
			}
		}
	}
}
GQL;

bdb($shopifyHttp->post($shopifyBase, [
	'query' => json_decode($query)
]));

Any thoughts? I've tested the POST request in Postman and works and this was the PHP HTTP code for that...

<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();
$request->setUrl('https://xxxxx.myshopify.com/admin/api/2021-01/graphql.json');
$request->setMethod(HTTP_Request2::METHOD_POST);
$request->setConfig(array(
  'follow_redirects' => TRUE
));
$request->setHeader(array(
  'X-Shopify-Access-Token' => 'xxxxx',
  'Content-Type' => 'application/json',
  'Cookie' => '_shopify_fs=2021-03-31T10%3A14%3A46Z; _y=82249b91-c91c-4631-8cb9-2a859e3e756e; _s=5be7df5e-f9a6-45a9-a472-e7f262f54a8b; _shopify_y=82249b91-c91c-4631-8cb9-2a859e3e756e; _shopify_s=5be7df5e-f9a6-45a9-a472-e7f262f54a8b'
));
$request->setBody('{"query":"  query {\\n    shop {\\n      name\\n      primaryDomain {\\n        url\\n        host\\n      }\\n    }\\n  }","variables":{}}');
try {
  $response = $request->send();
  if ($response->getStatus() == 200) {
    echo $response->getBody();
  }
  else {
    echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
    $response->getReasonPhrase();
  }
}
catch(HTTP_Request2_Exception $e) {
  echo 'Error: ' . $e->getMessage();
}

 

Link to comment
Share on other sites

I ended up using Guzzle to do, for example, the following:

// Shopify init
function shopifyQL($query) {

	$shopifyHost = "xxxxx.myshopify.com";
	$shopifyPassword = "xxxxx";
	$graphqlEndpoint = "https://$shopifyHost/admin/api/2021-01/graphql.json";
	$client = new \GuzzleHttp\Client();

	$response = $client->request('POST', $graphqlEndpoint, [
		'headers' => [
			'Content-Type' => 'application/json',
			'X-Shopify-Access-Token' => $shopifyPassword,
			'X-Shopify-Api-Features' => 'include-presentment-prices'
		],
		'json' => [
			'query' => $query
		]
	]);

	$json = $response->getBody()->getContents();
	$body = json_decode($json, true);
	$data = $body['data'];
	return $data;

}

// Get Shopify shop defaults (useful for currency checks)
wire()->addHookMethod('Page::shopifyShop', function($event) {
	$page = $event->object;

	$query = <<<GQL
	query {
	  shop {
		name
		primaryDomain {
		  url
		  host
		}
	  }
	}
	GQL;

	// Get cache only if it's less than or equal to 1 month
	$result = wire('cache')->get('shopifyShop', WireCache::expireMonthly);
	if (!$result) {
		$result = shopifyQL($query);
		wire('cache')->save('shopifyShop', $result, WireCache::expireMonthly);
	}
	$event->return = $result;
});

 

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...