> ## Documentation Index
> Fetch the complete documentation index at: https://archie.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Variables

> Parameterize GraphQL operations with typed variables. The right move for reusable, dynamic, and safe queries.

Variables let you parameterize a GraphQL operation. The operation document stays static; the values come in through a separate variables object. That's the right pattern for any query you'll run more than once with different inputs — and for any query that takes user input.

## Why use variables

| Reason          | Why it matters                                                                                                                                              |
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Reusability** | The same operation runs with different inputs. No string concatenation.                                                                                     |
| **Type safety** | Variables are declared with types. The server validates them against the schema.                                                                            |
| **Safety**      | Values are passed separately from the operation, eliminating an entire class of injection bugs that come from interpolating user input into a query string. |
| **Caching**     | Clients and servers can cache the parsed operation document and key it by variables.                                                                        |

In the API Explorer, the **Variables** panel sits below the editor. It accepts a JSON object whose keys match the variable names declared in your operation.

## Declaring variables

Replace the static value with `$variableName`, then declare the variable's type at the top of the operation. Variable types must match the schema — for example, a filter argument expects a `StudentsFilter` input type.

```graphql theme={null}
query MyQuery($domain: String) {
  students(filter: { email: { contains: $domain } }) {
    items {
      id
      firstName
      email
    }
  }
}
```

```json theme={null}
{
  "domain": "example.com"
}
```

The `$` prefix is part of the syntax — it tells GraphQL "this is a variable reference, look it up in the variables object."

## Multiple variables

Declare each one with its type. Pass them all in the same variables object.

```graphql theme={null}
query MyQuery($name_start: String, $status: Boolean) {
  students(
    filter: {
      firstName: { starts_with: $name_start }
      isActive: { equals: $status }
    }
  ) {
    items { id firstName email }
  }
}
```

```json theme={null}
{
  "name_start": "M",
  "status": true
}
```

## Complex variable types

Variables aren't limited to scalars. Pass entire filter objects, sort orders, and other input types.

```graphql theme={null}
query MyQuery(
  $filter: StudentsFilter
  $first: Int
  $orderBy: StudentsOrderBy
) {
  students(
    filter: $filter
    first: $first
    orderBy: $orderBy
  ) {
    count
    items {
      id
      firstName
      lastName
      age
    }
  }
}
```

```json theme={null}
{
  "filter": {
    "email": { "contains": "example" },
    "firstName": { "starts_with": "M" }
  },
  "orderBy": { "lastName": "ASC" },
  "first": 2
}
```

The exact type names — `StudentsFilter`, `StudentsOrderBy`, etc. — come from your schema. Open the **Documentation** panel in the Explorer or click a type name in the editor to find the right type for any argument.

## Required vs optional

Append `!` to a variable type to make it required. Without `!`, the variable is optional — leaving it out of the variables object produces a `null` value at runtime.

```graphql theme={null}
mutation Create($input: StudentsCreateInput!) {
  createStudents(input: $input) {
    id
  }
}
```

`StudentsCreateInput!` is required — the operation will not run without it. `StudentsCreateInput` (no `!`) is optional, and you'd typically only use that for arguments that have a server-side default.

## Default values

You can give a variable a default that applies when the variables object omits it.

```graphql theme={null}
query MyQuery($first: Int = 10) {
  students(first: $first) {
    items { id firstName }
  }
}
```

The default is applied by the GraphQL parser before validation, so the server treats the operation as if `$first: 10` was supplied.

## Outside the Explorer

Every GraphQL client library — Apollo, urql, graphql-request, etc. — accepts an operation string and a variables object as separate arguments to its query function. The shape on the wire is the same:

```json theme={null}
{
  "query": "query MyQuery($domain: String) { students(filter: { email: { contains: $domain } }) { items { id email } } }",
  "variables": { "domain": "example.com" }
}
```

That separation is what gives you the security and caching benefits — the operation is fixed, only the variables vary per call.

## FAQ

<AccordionGroup>
  <Accordion title="Should I use variables even for one-off queries?">
    For anything that takes user input — search terms, filters, ids from URL params — yes. It's the simplest way to avoid both injection bugs and quoting bugs. For static queries that never change, inlining the values is fine.
  </Accordion>

  <Accordion title="What's the right variable type for a filter argument?">
    The schema has a generated input type for every table's filter — typically `<TableName>Filter` (for example, `StudentsFilter`). Open the Documentation panel and look at the argument's type — that's the type to use for the variable.
  </Accordion>

  <Accordion title="Can a variable be used as a field in the response?">
    No. Variables only appear in argument positions. To return different fields per call, build the operation document on the client or use [GraphQL fragments](#) for reusable selection sets.
  </Accordion>

  <Accordion title="What happens if I pass a variable of the wrong type?">
    The server returns a validation error before running the operation. The error includes the variable name, the expected type, and the value that was passed.
  </Accordion>

  <Accordion title="Can I use variables in subscriptions and mutations too?">
    Yes — variables work the same way in queries, mutations, and subscriptions. The variable types differ (input types for mutations, the same filter inputs for subscriptions and queries) but the syntax is identical.
  </Accordion>
</AccordionGroup>
