← Back to all tutorials

Query Variables

Learn how to use query variables to make GraphQL queries dynamic, reusable, and safe.

Query Variables

So far, we've hardcoded values directly into our queries. In real applications, you need dynamic values — like a user selecting a game from a list. That's where query variables come in.

The Problem with Hardcoded Values

This works, but it's not flexible:

{
  game(id: "1") {
    title
    platform
  }
}

In a real app, the ID would come from user interaction (clicking a card, navigating to a page, etc.).

Using Query Variables

Query variables let you pass values separately from the query string:

query GetGame($id: ID!) {
  game(id: $id) {
    title
    platform
    reviews {
      rating
      content
    }
  }
}

Variables are passed as a separate JSON object:

{
  "id": "1"
}

Variable Declaration Syntax

Variables are declared after the operation name with a $ prefix:

query OperationName($variableName: Type!) {
  field(argument: $variableName)
}

Rules:

  • Variable names start with $
  • They must have a type that matches the schema
  • Add ! to make them required
  • They can have default values

Default Values

You can set defaults that are used when no value is provided:

query GetGames($limit: Int = 10, $offset: Int = 0) {
  games(limit: $limit, offset: $offset) {
    id
    title
  }
}

Multiple Variables

You can use multiple variables in a single query:

query GetFilteredGames($platform: String!, $minRating: Int) {
  games(platform: $platform) {
    title
    reviews(minRating: $minRating) {
      rating
      content
    }
  }
}
{
  "platform": "PS5",
  "minRating": 8
}

Using Variables in Apollo Sandbox

In the Apollo Sandbox, you'll find a "Variables" panel at the bottom. Enter your variables as a JSON object there. The sandbox provides auto-completion for variable names based on your query.

Variables with Frontend Frameworks

Here's how variables work with Apollo Client in React:

import { useQuery, gql } from '@apollo/client';

const GET_GAME = gql`
  query GetGame($id: ID!) {
    game(id: $id) {
      title
      platform
    }
  }
`;

function GameDetail({ gameId }) {
  const { loading, error, data } = useQuery(GET_GAME, {
    variables: { id: gameId },
  });

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error!</p>;

  return <h1>{data.game.title}</h1>;
}

Why Use Variables?

  • Security — prevents injection attacks (values are validated against types)
  • Performance — the query string stays constant, enabling caching
  • Reusability — same query, different data
  • Cleaner code — no messy string interpolation

Key Takeaways

  • Variables make queries dynamic and reusable
  • Declare them with $name: Type after the operation name
  • Pass values as a separate JSON object
  • Variables provide type safety and prevent injection
  • Default values are supported with = defaultValue

Next episode: Related Data — how to model and query complex relationships!