Skip to main content
GraphQL Basics
CHAPTER 08 Beginner

Query Arguments and Variables

Updated: May 13, 2026
20 min read

# CHAPTER 8

Query Arguments and Variables

1. Introduction

In previous chapters, we hardcoded values directly into our queries, such as user(id: "1"). However, in real-world applications, data is dynamic. A user clicks a specific product, or types a search term into an input box. You cannot hardcode these values. In this chapter, we will learn how to make our GraphQL queries dynamic using Arguments and, more importantly, how to pass those arguments securely using Variables from the frontend.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Understand how to pass arguments to fields in a query.
  • Identify the problems with string concatenation (hardcoding) in queries.
  • Define and use GraphQL Variables in your operations.
  • Combine variables with Operation Names to create reusable queries.

3. Beginner-Friendly Explanation

Imagine a coffee machine. A static query is a button that only ever makes a "Medium Black Coffee." An Argument is like adding dials to the machine. You can turn the dial to "Large" and another dial to "With Milk."

But how does the machine know what settings you want if you are using an app? You use Variables. Instead of building a new button for every possible combination, you build one generic button (the Query), and when you press it, you send a separate slip of paper (the Variables) that says "Size: Large, Milk: Yes." The machine reads the slip and makes exactly what you want.

4. Real-World Examples

  • Search Bar: A user types "Laptop" into a search bar. The frontend sends a single, reusable SearchProducts query to the server, passing "Laptop" as a Variable.
  • Pagination: When a user clicks "Page 2" on a list of articles, the frontend sends a query passing the variables limit: 10 and offset: 10.

5. Detailed Code Examples

Let's look at the wrong way and the right way to handle dynamic data.

The Wrong Way (Hardcoded / String Concatenation): *Do not do this in your JavaScript! It is prone to errors and injection attacks.*

javascript
123
// BAD PRACTICE
const id = getSelectedUserId();
const query = `query { getUser(id: "${id}") { name } }`;

The Right Way (Using Variables): First, we write the query with variable definitions. Variables in GraphQL always start with a dollar sign ($).

graphql
123456789
# 1. Define the Operation Name and the Variables it accepts
query GetUserById($userId: ID!) {
  
  # 2. Pass the variable into the field argument
  getUser(id: $userId) {
    name
    email
  }
}

Then, from the client (JavaScript/PHP), we send a JSON payload containing BOTH the query and a separate variables object.

json
123456
{
  "query": "query GetUserById($userId: ID!) { getUser(id: $userId) { name } }",
  "variables": {
    "userId": "42"
  }
}

6. Query Examples (Pagination)

Arguments are not just for IDs; they are perfect for filtering and pagination.
graphql
123456
query GetProducts($limit: Int, $category: String) {
  products(limit: $limit, category: $category) {
    name
    price
  }
}

Variables Payload:

json
1234
{
  "limit": 5,
  "category": "ELECTRONICS"
}

7. Mutation Examples

Variables are absolutely critical for Mutations, where you are passing large amounts of user-inputted data (like a signup form).
graphql
123456
mutation RegisterUser($name: String!, $email: String!, $pass: String!) {
  createUser(name: $name, email: $email, password: $pass) {
    id
    success
  }
}

8. Schema Examples (Input Types)

If a mutation requires many arguments, the schema can become messy. We can use input types in our schema to group variables together.

Schema SDL:

graphql
123456789
input UserInput {
  name: String!
  email: String!
  age: Int
}

type Mutation {
  createUser(input: UserInput!): User
}

The Query with Input Variable:

graphql
12345
mutation CreateNewUser($userData: UserInput!) {
  createUser(input: $userData) {
    id
  }
}

9. Best Practices

  • Never Concatenate Strings: Always use GraphQL variables to pass dynamic data. It allows the server to cache the query structure and protects against injection vulnerabilities.
  • Match the Types Exactly: If your schema says an argument is an Int!, your variable definition must also be $myVar: Int!. If they don't match, GraphQL will throw a validation error before executing the query.
  • Use Default Variables: You can assign default values to variables directly in the query. Example: query GetPosts($limit: Int = 10) { ... }

10. Common Mistakes

  • Forgetting the $ symbol: Variables must be prefixed with $ in the query string, but *not* in the JSON variables payload sent from the client.
  • Type Mismatch: A common error is defining a variable as a String when the schema requires an ID.

11. Mini Exercises

  1. 1. Look at this query: query Search($term: String!) { ... }. Is the $term variable required or optional?
  1. 2. Write the JSON variables payload to pass the word "Shoes" into the $term variable.

12. Coding Challenges

Challenge 1: Write a query named UpdateStock. It should take two variables: $itemId (an ID, required) and $amount (an Int, required). Pass these variables into a mutation field called changeInventory.

13. MCQs with Answers

Question 1

What symbol is used to denote a variable inside a GraphQL query string?

Question 2

Why is using GraphQL Variables better than injecting string variables directly into the query?

Question 3

If an argument groups many scalar fields together (like a form submission), what special type should be defined in the Schema?

14. Interview Questions

  • Q: Explain how a client application sends dynamic data to a GraphQL server using variables.
  • Q: What is an input type in GraphQL and when would you use it instead of standard arguments?
  • Q: How does GraphQL handle type validation for variables?

15. FAQs

Q: Can I use arguments on nested fields, not just the root query? A: Yes! This is a superpower of GraphQL. You can do this: query { user(id: "1") { name, posts(limit: 5) { title } } }.

Q: Do I need an Operation Name to use variables? A: Yes. In order to define the variable types (e.g., ($id: ID!)), you must provide an Operation Name or at least the query or mutation keyword.

16. Summary

In this chapter, we learned how to build dynamic, reusable queries using Arguments and Variables. We discovered that building queries via string concatenation is an anti-pattern. Instead, we define Variables starting with a $ in our query definition, and pass a separate JSON dictionary containing the actual values. We also learned how to use input types to cleanly manage complex data submissions.

17. Next Chapter Recommendation

We have mastered fetching data. Now it is time to focus entirely on changing it. Proceed to Chapter 9: GraphQL Mutations to learn how to securely create, update, and delete data on the server using GraphQL.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·