Variables
Variables let you pass dynamic values to a query without string-concatenation. Declared in the operation signature, used as $name in the body, sent separately as JSON.
Variables for filters, pagination, mutations
EXAMPLE
# Query with variables — the canonical shape
query FeedPage($first: Int = 20, $after: String, $tag: String) {
posts(first: $first, after: $after, tag: $tag) {
edges {
cursor
node {
id
title
author { name avatar }
}
}
pageInfo { endCursor hasNextPage }
}
}
# Variables JSON sent alongside
{
"first": 10,
"tag": "performance"
}
# Default values — $first defaults to 20 above
# Required types — Int! marks 'not nullable'
query Post($id: ID!) {
post(id: $id) { title }
}
# Variables in directives
query Post($id: ID!, $withComments: Boolean!) {
post(id: $id) {
title
comments @include(if: $withComments) { body }
}
}
# Apollo Client — pass variables typed
const FEED = gql`
query Feed($first: Int, $after: String) {
feed(first: $first, after: $after) { id title }
}
`;
const { data } = useQuery(FEED, {
variables: { first: 10, after: null },
});
# urql / graphql-request work the same way
const data = await request(url, FEED, { first: 10, after: null });
# NEVER inline user input as a string
# BAD — leaks like SQLi for GraphQL
const q = `query { user(id: "${userId}") { email } }`;
# GOOD — variables, every time
const q = `query ($id: ID!) { user(id: $id) { email } }`;
await request(url, q, { id: userId });
Why it matters
Variables aren’t just ergonomic — they’re the security boundary. String-interpolating user input into a query is an injection class; variables make the payload structurally inert.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
query GetUser($id: ID!) { user(id: $id) { id name } }
# variables: { "id": "42" }
Try it Yourself »
Discussion
Loading…