API Rate Limits and Working with GraphQL

Graphql rate limits

This is a complementary blog post to a video from the ShopifyDevs YouTube channel. This is the second post of a three-part series created by Zameer Masjedee, a Solutions Engineer with Shopify Plus. Today, Zameer will build on the foundations covered in his first post, An Introduction to Rate Limits, by examining the benefits of GraphQL, why it’s recommended, and how it differs from REST APIs. 

Note: All images in this article are hyperlinked to the associated timestamps of the YouTube video, so you can click on them for more information.

What is GraphQL?

GraphQL was designed to address deficiencies that the REST APIs weren't really structured to deal with. It simplified a few things. Instead of having our standard post, get, put, and delete requests like we do with REST, every GraphQL request is categorized as either a query or a mutation.

"GraphQL was designed to address deficiencies that the REST APIs weren't really structured to deal with."

A query simply reads data, and a mutation does everything else, like creating, updating, and deleting that data. 

GraphQL gives us the ability to query a lot of information. Like we discussed in the first part of this tutorial, An Introduction to Rate Limits, it’s typically pretty cheap. It costs about one point to receive a single object, and standardized mutations cost about 10 points.

You might also like: Getting Started with GraphQL.

One advantage of working with GraphQL concerns the number of HTTP requests you have to make to fetch all the data you might be interested in with our REST APIs.

For example, let’s say we're talking about a product. If you have an ID of a product and you want to fetch all of the product data, but you also want to fetch all of the product’s images, variants, and metafields, that would be four unique HTTP calls, because those are all independent endpoints with our REST implementation. 

That would take up one tenth of your bucket, and with the two calls per second refresh rate, it would take two seconds to refill. 

GraphQL works a little bit differently. It allows you to fetch data from multiple related objects in a single GraphQL query. Below, I show you how.

Working in the Shopify GraphQL app

Let’s jump to my demo store, where I’ve installed our Shopify GraphQL app. It looks like this: 

Graphql rate limits: screenshot taken from YouTube video

You’re going to need to install this on your development store as well. It's really useful for GraphQL testing within the admin. 

You can see I’ve written a really quick query. I want to take a look at the first product of my store, products(first: 1), and I want to get the ID and description of that product. I also want to take a look at the first variant, variants(first: 1), on my store and I want to get the barcode of that variant. Finally, I want to get some information about images(first: 1) and metafields(first: 10)

Let’s take a look at what happens when we run this request.

Graphql rate limits: gif taken from YouTube video

You see that it yields only what we asked for. You see the ID, the description, and the variant information that I requested, but none of the stuff that we didn’t need, such as variant IDs. The data we’re receiving back suggests there’s no overfetching. I get back what I've asked for. 

The same does not apply to REST, unfortunately. When I request information for an order ID, I get back everything associated with that order. It yields back about 350 lines of JSON data. In Insomnia, I can't pass any field parameter to specify the field that I want. 

Graphql rate limits: gif taken from YouTube video

GraphQL, unlike REST, enables us to make some modifications. For example, let’s go create another query, where I want to get a specific order back.

Graphql rate limits: gif taken from YouTube video

This is the GraphQL query that's meant to fetch the exact same thing as the Insomnia example above, a specific order, but I just want one property. We want to know if it's fullyPaid or not so that we could store it in our database or do something similar with it.

When we make that request, it comes back as true. It is fully paid, and it's only costing me one point out of my available 1,000 to find that out, and I'm restoring at 50 points per second.

Graphql rate limits: screenshot taken from YouTube video

I get back a really robust understanding of exactly where my weight limit is and how much I have left.

Now, you get something similar when you make a REST API call. I chose to use Insomnia, but you can use any other HTTP client you want, such as Postman for example. Let’s go back to the order request that I made with Insomnia. 

Graphql rate limits: gif taken from YouTube video

In the header response, we passed back the Shopify-specific header called x-Shop-api-call-limit, which tells you how much of your API rate limit you've used. 

When you make that call a few times rapidly, you'll see that this does change your rate limit. The reason it takes a little while is because every second you're restoring two of those calls due to the leaky bucket algorithm. But it always gives you an exact snapshot of how much more API rate limit you have. 

Benefits of working with GraphQL instead of REST

Another key benefit of working with GraphQL is that it enables Shopify to better understand what data you're making requests to. 

When you make a call to a REST API, we don't know what data you're using and what you're not. This has an impact on how we understand your relationship with Shopify. When you use a GraphQL mutation, we have insight into the specific fields you’re fetching or specific mutations you’re making. That means that when a deprecation is coming, or a new product is being released that we need beta testers for, we can reach out directly to you because we know you’ll be impacted.

There are a few other benefits to working with GraphQL, but the final one I want to highlight is that GraphQL has its own schema. You know exactly what you have access to when you're putting together your queries and your mutations, and it prevents it from being as error-prone as a REST implementation has the potential to be.

"From a foundational, structural, and architectural perspective, the benefits the GraphQL technology offers allow us to do things we can't do with our REST API."

Foundationally and structurally, from an architectural perspective, the number of HTTP requests you have to make and the amount of data that you get are really important pieces. But aside from that, the benefits that the technology offers allow us to do things we can't necessarily do with our REST API. One example of a benefit that GraphQL offers is regarding our bulk operations.

Bulk operations APIs: a GraphQL-specific capability

Shopify has some capabilities that are exclusive to GraphQL, and they're typically things that lead to overall efficiency. Opening yourself up to more capabilities is an important consideration when it comes to picking between REST and GraphQL. 

"Opening yourself up to more capabilities is an important consideration when it comes to picking between REST and GraphQL."

So, what is a bulk query mutation?

A bulk query mutation is the ability for you to give Shopify one long-running task to execute on your behalf, and inform you when it's done.

There are two steps on your end: 

  1. Give us the query, we'll process it and will notify you when it's done
  2. Download the data

Typically, if you don’t use the bulk query, you’ll have to paginate your data sets. For REST, for example, you only have 250 items returned in a response. For GraphQL, it's cost-based but, at the end of the day, you're still limited to a certain number per request. That's not the case with a Bulk Operation API

Let’s look at the example from our tutorial on performing bulk operations with the GraphQL Admin API in the developer documentation.

Graphql rate limits: screenshot taken from YouTube video

This could be a hundred thousand products. This could be a million products. Obviously, that would take a little bit more time to process, but ultimately we’re able to get a response back that includes all of that data, specifically the ID and title so that we can store it in our own servers. 

You give us a request, we process it. We allow you to pull another endpoint to see when the status is complete, and ultimately download the file. 

You might also like: An Introduction to Rate Limits.

What are some use cases for this?

Perhaps you install an app that does something like data processing, and you want to show some beautiful dashboards to your merchants. You have the ability to download all their data in bulk when they first install your app, so you can run your business intelligence (BI) tools and give them the insights that they're looking for.

Alternatively, say you’re working with webhooks. They’re really useful because their deliveries are always guaranteed. You can implement reconciliation or a scheduled cron job with a bulk mutation, where every day, it'll go and fetch all the orders from the previous day.

In the above example we're fetching all products, but you can very easily pass other parameters as well. Say you only want ones that have been created on this particular day. You know that you can have an exhaustive list of all the data that you may or may not have received all the webhooks for. 

Updating inventory items using bulk query operations

Another really cool use case is our inventoryBulkAdjustQuantityAtLocation mutation. Bit of a mouthful, but really useful.

Graphql rate limits: screenshot taken from YouTube video

It allows you to update up to 100 different inventory item quantities at a single location in a single mutation. In REST, that would be one call per each inventory level so to update 100, that's 100 calls. In GraphQL, that's one mutation that only costs 10 points out of your 1,000-point bucket or out of your 50 restore rate. 

Building with GraphQL

As you can see, GraphQL provides many benefits, especially when you’re working with users who have multiple retail locations or other factors that affect inventory, where you want to keep Shopify in sync with other systems. Some of these more efficient and scalable requests are focused on GraphQL, so it's definitely worth a deep dive.

Stay tuned for the final video in this series on our ShopifyDevs YouTube channel, where we'll be exploring an API real limit by using a Ruby application to make calls to the Shopify API gem.

Grow your business with the Shopify Partner Program

Learn more