How to use GraphQL variables to give queries type safety

GraphQL variables let you create reusable queries and mutations that are type-safe. This article explains how to use them, with examples.
Published
October 22, 2021
Updated
March 25, 2024
Category

Guides

GraphQL variables let you build queries and mutations that accept values from your application or users. For example, a query can accept a variable with a search term provided from a search box, or the value of a column filter from a table. You can also provide a variable to a mutation to use that variable to update data in your backend.

This article shows you how to use GraphQL variables to accept input and enforce type safety in your queries by restricting what kinds of values can be passed to them.

What are GraphQL variables?

GraphQL variables work the same way as variables in any other programming language: Each variable has a name that is used to access the value that is stored in it. 

GraphQL variables are used to pass values from your application code to your query. Here's an example of a GraphQL query that uses a variable to accept a value from the code that calls it:

This example query accepts a $pet_name variable and then uses it to find the pet with the matching name. It’s easy to spot variables in GraphQL queries — they’re always prepended with a dollar symbol ($). The response to this query would look something like this, including the additional color and species information specified in the query:

How to define and use variables in GraphQL queries

GraphQL query variables are defined separately to the query itself. When the query is executed, the variables will be inserted into the query, and matching results returned in the API’s response. The below example shows a query and variables, defined in a JSON object for use in HTTP requests to a GraphQL API:

Separating the query from the values that will be inserted as variables makes it easy to write reusable GraphQL queries. When making your requests, you will pass the query and variables as separate objects.

Default values for GraphQL variables

To set a default value for a variable, so that the query can be used without any input, you can supply the default when defining the variable:

Above, the variable $pet_name has the default value "Sam". If no value is provided, the GraphQL query will use this value.

Creating and updating data using GraphQL mutations with variables

GraphQL mutations can create, update, and delete data on the server via your API. Passing variables to mutations works the same way as with queries. 

Below is an example mutation defined in a GraphQL API:

Note that the mutation actually accepts two variables: The $id variable is used to locate a pet record, and the $new_name variable is used to update the name. Below is the frontend code that can be run to call the UpdatePetName mutation and update the backend data:

The self-documenting nature of GraphQL makes it straightforward to see what's going on and make adjustments to your queries so that you get the exact data you require.

Making GraphQL queries from your website or app

Contentful provides a GraphQL API for interacting with your content, like blog posts, media, comments, products, and other data you have created on our Composable Content Platform. It's a great place to learn about how to use GraphQL: Our GraphQL Playground provides a graphical interface for building and testing queries with your data. You can also use our GraphiQL explorer to interact with content in your Contentful space using GraphQL from your browser.

You can also use our GraphiQL explorer to interact with content in your Contentful space using GraphQL from your browser.

In the example shown in the GraphiQL explorer above, the top box in the left column shows a GraphQL query that has been entered. The query is defined with a $slug variable. 

Within the query, the $slug variable is used as an argument for a WHERE clause. When retrieving items from the API, the query will return results where the blog post's slug (that is, the unique part of the blog post’s web address) matches the value of $slug.

Once you have constructed and tested your queries and mutations, you can use them to access data from your application or website via HTTP. Any language that can make an HTTP request can interact with GraphQL, including JavaScript, Python, PHP, and Ruby.

GraphQL query variables example

This example shows how to use the JavaScript Fetch API to make a GraphQL request from a web browser, mobile app, or Node.js:

Above, the query and variables are defined as separate JavaScript objects, and then passed to the HTTP request to the GraphQL API. As this example is using the Contentful GraphQL API to run it, you'll need to replace SPACE_ID and ACCESS_TOKEN with those from your own Contentful account.

GraphQL variable types and type safety

In the examples above, you will see: String! appear following the slug argument when querying for BlogPost items. This is the type of the variable that is expected. If you try to pass a value that’s not a string to the variable, you will receive an error and the query will not run.

Type safety solves a lot of problems for developers by preventing unexpected input and unexpected results. For example, passing a string where a number is expected may cause your application to crash when performing arithmetic operations.

Predictable code means that errors are caught during testing, and reduces problems for users on the frontend when you deploy your final product. Using types on the backend also helps protect your data integrity and prevent things like injection attacks.

GraphQL has several built-in basic types: String, Int, Float, Boolean, and ID. These scalar types form the building blocks of object types. You can also define your own object types to model your own data structures and behaviors.

Going further with custom types in GraphQL

There are several variable data types available in Contentful’s GraphQL API. As well as the built-in GraphQL scalar data types, you can also pass variables to a query that have entry-specific and API-specific object types that are constructed from scalar types. For example, you may define a BlogPost object type in your schema that holds scalar values for the slug, title, and other blog post attributes as String scalar values.

To inspect the types available in your schema, click on the Docs link at the top right of the Contentful GraphiQL explorer:

To inspect the types available in your schema, click on the Docs link at the top right of the Contentful GraphiQL explorer.

Then, click on Query:

The Contentful GraphiQL explorer with the Query link highlighted.

And find the content type you’d like to inspect:

The Contentful GraphiQL explorer with content highlighted.

From here you can inspect the structure of the objects returned by your GraphQL API, allowing you to understand what data can be queried and used in conditions, and build your frontend code to match your backend architecture.

TypeScript and GraphQL help keep the data in your front and back ends consistent.

GraphQL variables and type safety, in combination with typed languages like TypeScript, ensure that your data is consistent across your front- and backend, making it easier to develop complex applications and improving the reliability of your apps for your end users.

How to use GraphQL variables as keys in WHERE clauses

One issue developers may face when using variables in GraphQL queries is that you can’t use variables in GraphQL as keys in WHERE clauses. You can work around this by using an additional variable that modifies the query.

For example, to create a GraphQL query that fetches calendar events and shows either future events in ascending order or past events in descending order, you would pass in the two supported GraphQL variables that are used in the query:

  • $orderdate_ASC or date_DESC

  • $date — as an ISO string

Then you need to use a third dynamic variable to control whether the API returned events before (date_lt — date less than) or after (date_gt — date greater than) the $date. By using a calculated string as a query variable, the query is modified depending on the value of the JavaScript dateFilter variable:

You'll notice that the $order GraphQL variable is of type EventOrder, which is a custom API- and entry-specific object type that exists in the GraphQL schema we explored above.

Choosing components and platforms that support GraphQL makes it easier to build apps and frontends

GraphQL lets frontend developers get on with the job of developing engaging user experiences rather than crafting custom backend endpoints, in many cases a necessity when working with REST APIs. Schema stitching lets you combine different GraphQL APIs into a single endpoint, further streamlining your application code and improving the responsiveness of your applications by reducing the number of backend requests required to keep their data up to date.

Contentful is a composable content platform that lets you define and manage your content and deliver it to your apps, websites, and other channels from a single, centrally managed source. It removes the need to implement CMS functionality, and gives creative teams the tools they need to build and publish content, letting engineers focus on building and improving their products.

You can build your personal blog or an entire web publishing or ecommerce ecosystem on Contentful. Our extensive support for GraphQL (including these neat tutorials) will help get you started.

Start building

Use your favorite tech stack, language, and framework of your choice.

About the authors

Don't miss the latest

Get updates in your inbox
Discover new insights from the Contentful developer community each month.
add-circle arrow-right remove style-two-pin-marker subtract-circle remove