GraphQL and Shopify

What is GraphQL

GraphQL is a query language for your API, and a server-side runtime for executing queries by using a type system you define for your data. A GraphQL query is a string interpreted by a server that returns data in a specified format. Here is an example query:

{
  node(id: "Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0Lzk4OTUyODE0NzU=") {
    id
    ... on Product {
      title
    }
  }
}

And here is the response to that query:

{
  "data": {
    "node": {
      "id": "Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0Lzk4OTUyODE0NzU=",
      "title": "Arena Zip Boot"
    }
  }
}

GraphQL vs REST

The problems GraphQL addresses may sound familiar to anyone who’s worked on a REST API or has consumed a REST API before:

REST | Fetching associated data often requires multiple HTTP calls.

REST APIs are built on the principle that every endpoint should return only one type of resource. For instance, when fetching GET /products/1, you should receive the information for product 1 (i.e. title, description), but nothing more. Following this principle means that if you want a product’s variants, images, and metafields you would end up having to do at least four HTTP calls.

REST | Apps receive way more data than they actually need.

To solve the above problem, we end up breaking away from “true” REST APIs by embedding certain associations to certain end-points when the need arises. For instance, GET /products/1 now returns information about the product, but also its variants, images, and options. Ultimately we end up with one-size-fits-all responses where you cannot request less nor more than what we give you.

REST | We don’t know what data an app actually needs.

Related to the above problem, when an app requests a REST endpoint, we have no way of knowing if they are actually using every piece of data we return. It’s as if you did a SELECT * to a SQL database. This is problematic because when we need to make breaking changes like remove an attribute from a response it’s near impossible to know who it will affect. We know what clients call what end-point, but we don’t know what subset of those clients are using the attribute we are trying to remove. It is also problematic when some attributes are costly to compute. If we had a way of knowing the app doesn’t need that costly attribute, we wouldn’t need to compute it in the first place.

REST | REST APIs are usually weakly-typed and lack machine-readable metadata.

While there exists some solutions to this problem (like JSON Schema), the reality is that most REST APIs do not provide this sort of metadata. This means apps rely on documentation that tend to fall out-of-date or worse are incomplete.

GraphQL | Everything is typed and everything you want to expose is part of a schema.

The days of not knowing what fields are accepted by what endpoint are over. In order to make something accessible via your GraphQL API, it needs to be part of the schema. Clients craft queries and get back only what they requested. Not only does this solve the over-fetching data problem, it also means as an API provider, we know exactly what each app is using, making it easier for us to evolve our API over time.

GraphQL | Documentation is a first-class citizen.

This means the documentation for your API will live side-by-side with the code that constitutes it. Combined with the typed schema, it means we can auto-generate accurate and up-to-date documentation whenever something changes.

GraphQL | Deprecation is a first-class citizen.

We can easily mark a part of our schema as deprecated and this will also be reflected in documentation. GraphQL tooling such as client libraries are also expected to output usage of deprecated fields to the developer using the tool.


Caution

Like any technology, GraphQL isn’t a silver bullet. It solves specific problems and comes with its own set of limitations. It is also still in its infancy and we’ll of course find issues as our usage grows, but we strongly believe in its concepts. We are also involved in the GraphQL community by actively contributing to the GraphQL Ruby gem, open-sourcing tools/libraries, as well as contributing to discussions in the GraphQL spec.

Learning Resources

To learn more about GraphQL, please visit: