Getting BigCommerce Data With GraphQL in WordPress

Topher DeRosia
BigCommerce Developer Blog
6 min readAug 31, 2020

I’ve been hearing about GraphQL for quite a few years now, but it was quite a while before I really looked into it and realized the QL stands for Query Language. At that point, it all kind of snapped into focus for me. Rather than send many GET variables in the URL for a REST query, you build a logical query in JSON and send it in the body of a POST request.

At its simplest, a GraphQL query is no different from any other HTTP call. In your preferred programming language you use an HTTP library to send the body and then you accept the request results. In reality, there are often authentication systems to navigate, query formatting to get exactly right, and many other things to think about.

In this post, I’m going to show you how to authenticate against your BigCommerce store and make an HTTP POST request to get your product data using GraphQL in WordPress.

The Code Example

The code I’m using as an example in this post is far too long to post in its entirety, so I’ll link here to the GitHub repository and just include fragments as examples.

The full code sample is a WordPress plugin that contains a PHP class that

  • Gathers all of the local authentication and path information and assigns them to class attributes
  • If there isn’t a GraphQL token it gets one from BigCommerce
  • Has a method that gets raw JSON back from the query request
  • Creates a shortcode to dump that JSON data to the screen for debugging

Let’s take a look at the important parts.

Authentication

In order to make a GraphQL query against BigCommerce, you must send an authentication token in a header. It’s different from a REST call though. REST calls require two headers, X-Auth-Token and X-Auth-Client, whereas GraphQL requires a single one, Authorization. Documentation for this is in the developer docs. Something important to note is that in order to get the Authorization token you have to make a REST call.

In order for that REST call to work there are two vital scopes that must be enabled on your API keys:

  • Storefront API Tokens
  • Storefront API Customer Impersonation Tokens

You can read complete documentation about making API keys. If you already have a BC4WP store set up and didn’t make your API keys yourself, they probably don’t have what you need. Once you have new keys, you can simply paste them into the API section of the BC4WP settings area like this:

Once you have your API keys set up, you can make a REST request to get the GraphQL authentication token. Here’s what that code looks like,

Once you get a token you can store it in a variety of ways. If you chose a short expiry then you should probably store it in a transient. If you chose a long one like I did, then you can store it in a WordPress option.

I have a method to look for a local copy of the token, and if it’s not there, get one using the above method. Here’s my local token method.

Now we have a token, whether we got it from a local store in WordPress or if it came directly from BigCommerce. Our next steps are to

  • Craft GraphQL headers
  • Craft the query
  • Send the query
  • Process the results

Crafting GraphQL Query Headers

All of the next several sections are part of one method in the example class. For GraphQL we only need 2 custom headers:

// Set up the headers$headers[ ‘content-type’ ] = ‘application/json’;$headers[ ‘Authorization’ ] = ‘Bearer ‘ . $this->auth_token;

Tokens are quite long, relatively speaking. Here’s an example from the documentation:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

So the actual value for the Authorization header is something like

Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Crafting The GraphQL Query

This is the real magic. Everything else is very normal WordPress code getting remote content. The GraphQL query dictates what data we’re going to be asking for. Here’s the one I’m using in my code:

I’m not going to go over everything in the query, but here are some important parts. This line:

products (first: 4) {

Indicates that I’m asking for the first 4 products available. Some other options look like this:

products (entityIds: [4917]) { // get one product by ID.products (entityIds: [4917, 4918]) { // get two products by ID.product(variantEntityId: 27098) { // get a variant of a product by ID

If you’re familiar with SQL, this would be similar to the WHERE clause.

The next important lines are these:

…responsiveImageFragment

They indicate that somewhere else in the query is a reusable fragment of a query. In this case, it’s at the bottom, and it’s the image sizes we want for these products. Rather than writing it out in the two places we need it, we write it once at the bottom and refer to it. The code it refers to is this:

fragment responsiveImageFragment on Image {
url320wide: url(width: 320)
url640wide: url(width: 640)
url960wide: url(width: 960)
url1280wide: url(width: 1280)
}

This fragment indicates what image sizes should be gotten for each product and variant.

Sending The GraphQL Query

Since we’re using WordPress we want to use one of the functions from the HTTP API. In this case I chose to use wp_safe_remote_post(). It takes two values; a URL and a set of arguments.

Formatting the URL

From the code:

$url = ‘https://store-' . $this->store_hash . ‘-’ . $this->channel_id . ‘.mybigcommerce.com/graphql’;

The URL always begins with the word “store” and then there’s a hyphen and then the store hash. Then another hyphen and the channel ID that we’re working with. Then it ends with ‘.mybigcommerce.com/graphql’

Next, let’s look at the arguments that get sent along with the request.

Formatting the Request

From the code:

// Set up the POST arguments. These need Headers, Method, and Body
// headers holds the headers array we created above
$args[ ‘headers’] = $headers;
$args[ ‘method’] = ‘POST’;

The first listed there is the array of headers that we made above. The second dictates the request type, which must be POST, or the request won’t work.

The last argument contains the body, and the code looks like this:

$args[ ‘body’ ] = wp_json_encode([
‘query’ => $query
]);

This takes the GraphQL query and assigns it to an array item called “query” and then encodes the whole thing to JSON. At that point it’s ready to be sent to BigCommerce with this code:

$request = wp_safe_remote_post( $url, $args );

Processing The Output

The result we get back from a wp_safe_remote_post() request is a full HTTP response, which means it comes with HTTP headers etc. All we really want is the body of the results. In this case, the results are also in JSON format, and we want a PHP array, so here’s the code we’re using:

$bc_data = json_decode( wp_remote_retrieve_body( $request ) );

Then $bc_data holds an array of the data about the products we asked for.

In this example class, I’ve made a shortcode which simply prints this output to the screen so you can see it. With this plugin activated you can place this shortcode on any page and see the results of the query:

[render_graphql_data]

In a real-world situation of course you would probably loop over the product results and process them any way you wish.

Summary

It took me a while to understand why GraphQL is better than REST. What I’ve come to realize is that REST doesn’t have a standardized, code accessible language. GraphQL is inherently that, a Query Language. This makes it far more powerful for programmatically constructing queries to get what you want, without having to make custom requests for each kind of REST endpoint.

The BigCommerce for WordPress does the work of building a store that most people need, but there will always be things that only a few individuals need. Using GraphQL they can fulfill those needs in a professional, consistent way.

--

--

Topher DeRosia
BigCommerce Developer Blog

Topher is a Senior WordPress Strategist at Camber Creative.