Variables, fragments and operation names

GraphQL Course · lesson 10 of 14 · 5 min read

How real clients send queries, rather than string concatenation.

Open this lesson in the learning hub

Key points

  • Variables keep values out of the query text. That makes the query a constant the server can parse-cache, and it removes the injection risk of interpolating user input.
  • A query with interpolated values is a different string every time, so nothing caches and every request pays full parse and validation cost.
  • Fragments name a reusable set of fields. They keep a large query readable and guarantee two parts of a UI request exactly the same shape.
  • Inline fragments select fields conditionally on a type, which is how you query a union or an interface - ... on Book { isbn }.
  • Always send an operation name. It is what appears in server logs, metrics and traces, and without it every query is anonymous and unattributable.
  • Aliases let one query fetch the same field twice with different arguments, which is often the cleanest way to avoid two round trips.

Example

# BAD - values interpolated into the query text.
query { user(id: "123") { name email } }
#   different string every request -> no parse cache, and any client-side
#   interpolation of user input is an injection risk

# GOOD - a constant query plus variables.
query GetUser($id: ID!, $first: Int = 10) {
  user(id: $id) {
    ...userFields
    orders(first: $first) {
      edges { node { id total ...moneyFields } }
    }
  }
}

fragment userFields on User { id name email }
fragment moneyFields on Order { currency total }

# variables, sent separately:
# { "id": "123", "first": 5 }

---
# ALIASES - the same field twice, different arguments, one round trip.
query Dashboard($userId: ID!) {
  recent: orders(userId: $userId, first: 5, status: COMPLETED) {
    edges { node { id total } }
  }
  pending: orders(userId: $userId, first: 5, status: PENDING) {
    edges { node { id total } }
  }
}

---
# INLINE FRAGMENTS - required for interfaces and unions.
query Search($term: String!) {
  search(term: $term) {
    __typename
    ... on Book   { title isbn }
    ... on Author { name bookCount }
  }
}

---
# The HTTP request a client actually sends:
# POST /graphql
# {
#   "operationName": "GetUser",     <- put this in your logs and metrics
#   "query": "query GetUser($id: ID!) { ... }",
#   "variables": { "id": "123" }
# }

Send a constant query plus variables and always name the operation - it is what makes caching, logging and metrics possible.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the GraphQL Course course, and every lesson in it is listed on the GraphQL Course contents page.