Skip to main content

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 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

ReasonWhy it matters
ReusabilityThe same operation runs with different inputs. No string concatenation.
Type safetyVariables are declared with types. The server validates them against the schema.
SafetyValues are passed separately from the operation, eliminating an entire class of injection bugs that come from interpolating user input into a query string.
CachingClients 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.
query MyQuery($domain: String) {
  students(filter: { email: { contains: $domain } }) {
    items {
      id
      firstName
      email
    }
  }
}
{
  "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.
query MyQuery($name_start: String, $status: Boolean) {
  students(
    filter: {
      firstName: { starts_with: $name_start }
      isActive: { equals: $status }
    }
  ) {
    items { id firstName email }
  }
}
{
  "name_start": "M",
  "status": true
}

Complex variable types

Variables aren’t limited to scalars. Pass entire filter objects, sort orders, and other input types.
query MyQuery(
  $filter: StudentsFilter
  $first: Int
  $orderBy: StudentsOrderBy
) {
  students(
    filter: $filter
    first: $first
    orderBy: $orderBy
  ) {
    count
    items {
      id
      firstName
      lastName
      age
    }
  }
}
{
  "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.
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.
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:
{
  "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

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.
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.
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.
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.
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.