skip to content

Operations & Documents

What a client sends: operations, selection sets, variables, fragments and the validation a document must survive — the fastest way to tell who has written GraphQL from who has only read about it.

part ofGraphQLoverview, primer and where to startread it →
on this pageshow

questions

page 1 of 2

Which literal value forms can a GraphQL argument take inline in a document?

level: juniorimportance: must knowfreq 58%

answer

  1. Eight shapes a value can take
  2. It looks like JSON and is not
  3. Bare names, not quoted strings
  4. Braces with unquoted field names
  5. Commas are only whitespace

basics

~20 s

Eight forms: Int, Float, String, Boolean, null, enum value, list and input object. Enum values and the true/false/null keywords are written bare, and an input object's field names are unquoted, so the syntax is not JSON.

solid answer

~40 s

A document can write eight kinds of input value inline: `Int` (digits, no decimal point, no leading zeros), `Float` (a fractional part or an exponent), `String` in double quotes or as a triple-quoted block string, `Boolean` as bare `true`/`false`, `null` as a bare keyword, an **enum value** as a bare name, a **list** in square brackets, and an **input object** in braces. The two that catch people are enums and input objects, because both look like JSON and are not: an enum value is written `WAITLISTED`, never `"WAITLISTED"`, and an input object's field names are bare names, as in `{ termCode: "2026-SPRING", credits: 4 }` rather than quoted keys. Commas are insignificant whitespace everywhere, so `[4 8 15]` is a legal list. Single quotes are not string syntax in GraphQL at all.

code

graphql · 12 lines
graphql
mutation {
  enroll(
    sectionId: "SEC-4471"
    status: WAITLISTED
    weighting: 0.75
    alternateSectionIds: ["SEC-4472" "SEC-4489"]
    preferences: { notify: true, maxCredits: 18, note: null }
  ) {
    enrollmentId
    status
  }
}

go deeper

for a junior

Be ready to write a correct argument list on a whiteboard without a schema in front of you. The marks are lost on the JSON habits: a quoted enum value and quoted input-object keys.

for a middle

Expect to explain why the grammar differs from JSON and to name where the same value grammar is reused, including directive arguments and default values. Knowing that commas are insignificant is a small but reliable signal.

for a senior

An interviewer will expect you to say when a bad literal fails and what that failure looks like: statically, before execution, as a request error with no data key rather than as anything a resolver ever sees.

for a principal

Own the consequence for tooling. Because literals are checked statically, a constant typo fails for everyone at once and can be caught in a build; that is an argument for keeping genuine constants in the document and pushing per-caller data out of it.

## Literal syntax is not JSON, and that is the whole lesson Most engineers meet GraphQL argument values after years of writing JSON, and the two look close enough that the differences read as typos rather than as a different grammar. They are a different grammar. The specification defines one `Value` production, and every place a value can be written uses it: a field argument, a directive argument, an element inside a list, a field inside an input object, and a default value in a definition. Learn the eight forms once and they apply everywhere. ## The eight forms **Int.** An optional minus sign and digits, with no decimal point, no exponent, and no leading zeros. `4`, `-27` and `1200` are Int literals; `007` is a syntax error. The built-in `Int` scalar is a signed 32-bit integer, so a literal outside that range is rejected rather than silently wrapped. **Float.** Digits with a fractional part, an exponent, or both: `3.5`, `-0.25`, `1.2e3`. A trailing dot with nothing after it is not legal. **String.** Double quotes only: `"SEC-4471"`. Single quotes are not string syntax in GraphQL at all; they are an illegal character in a document. There is a second string form, the **block string**, written with triple quotes. **Boolean.** The bare keywords `true` and `false`, lower case and unquoted. `"true"` is a String literal, and a `Boolean` argument rejects it. **Null.** The bare keyword `null`. It is a real value the caller can send, distinct from leaving the argument out. **Enum value.** A bare name: `WAITLISTED`, `ENROLLED`, `DROPPED`. Never quoted. The grammar deliberately excludes `true`, `false` and `null` from being enum values, so those three keywords can never be mistaken for enum names. **List.** Square brackets around zero or more values: `["SEC-4471", "SEC-4472"]`, or `[]`. Because the elements are themselves values, lists nest and may hold input objects. **Input object.** Braces containing `name: value` pairs, where the names are bare: `{ termCode: "2026-SPRING", credits: 4 }`. Quoting the field names, as JSON requires, is a syntax error. Order is not significant and a field name may appear at most once. ## Commas are decoration Commas in a GraphQL document are insignificant, exactly like spaces and line breaks. `[4 8 15]` is a legal list literal and `{ termCode: "2026-SPRING" credits: 4 }` is a legal input object literal. The comma exists so that humans can read a long line; nothing in the grammar needs it. That is the cleanest tell that you are not looking at JSON. ## Block strings A block string is delimited by three double quotes and may span lines. Common leading indentation is stripped from the value, so an argument written inside an indented selection set does not inherit the document's indentation. The only escape sequence inside a block string is an escaped triple quote, which is why a block string is a comfortable place to put text that is full of quotes and backslashes. The same syntax is used for descriptions in schema definition text, which is where most people see it first. ## A literal need not match the declared type exactly Two leniencies are specified, and they are the ones worth remembering: * Where a `Float` is expected, an **Int literal is accepted** and coerced — `credits: 4` satisfies a `Float` argument. The reverse does not hold: a Float literal is not a valid `Int`. * Where an `ID` is expected, both a **String literal and an Int literal** are accepted, because identifiers are opaque and servers differ on whether they look numeric. Custom scalars decide for themselves which literal kinds they accept, and the specification does not prescribe that. A custom date scalar conventionally takes a String literal, but that is a decision made by whoever defined the scalar, not a rule you can rely on across schemas. ## Who checks the literal, and when Literal values are checked statically, before anything executes, by the validation rule that requires values to be of the correct type. A quoted enum value or a Float literal in an Int position therefore fails the request outright: the response carries errors and no `data` key, and no resolver ran. This is a pleasant property — a typo in a constant fails identically for every caller, which means it fails in your own test run rather than for one unlucky user. ## Worked example Consider a course-enrolment graph whose `enroll` field takes an ID, an enum, a list and an input object. One document can exercise every literal form at once: ```graphql mutation { enroll( sectionId: "SEC-4471" status: WAITLISTED preferences: { notify: true, maxCredits: 18, note: null } alternateSectionIds: ["SEC-4472" "SEC-4489"] weighting: 0.75 ) { enrollmentId status } } ``` Note the four tells: the enum is bare, the input object's keys are bare, one list has no comma between its elements, and `null` is written as a keyword rather than as the string `"null"`. ## The two traps that actually show up The first is `status: "WAITLISTED"`. It reads correctly to anyone coming from JSON and is rejected, because a String literal is not an enum value. The second is `preferences: { "notify": true }`, which is a parse failure rather than a type failure — the document does not even reach validation. Both have the same cure: remember that the document is GraphQL source text, not a JSON payload, and that only actual text goes in quotes.

  • Where else in a GraphQL document or schema can these same literal forms appear?
    Everywhere a value is written, because the grammar defines one value production and reuses it: field arguments, directive arguments on both a document and a schema, elements inside a list literal, fields inside an input object literal, and default values in variable definitions and in argument and input-field definitions.
  • Is `4` accepted where a Float argument is expected, and is `4.0` accepted where an Int is expected?
    `4` is accepted for a Float and coerced; the leniency runs one way only, so `4.0` is not a valid `Int` and fails validation. An `ID` argument is more permissive still: it accepts a String literal or an Int literal, because identifiers are opaque and servers differ on whether they look numeric.
  • What is a block string, and when would you write one as an argument value?
    A block string is delimited by three double quotes, may span lines, and has its common leading indentation stripped, so it does not inherit the document's indentation. Its only escape sequence is an escaped triple quote, which makes it comfortable for text full of quotes or backslashes. The same syntax carries descriptions in schema definition text.

GraphQL literals read more like the settings block of a config file than like a JSON payload: names stand bare, and quotes are reserved for text that really is text.

saying these in an interview costs you the question

  • Quotes an enum value like a string
  • Quotes input object field names as JSON does
  • Thinks commas between list elements are required
  • Uses single quotes for a string literal
  • Writes 4.0 where the argument is an Int
  • Calls the argument list a JSON object

context

open as a page

What does GraphQL validation check between parsing a document and executing it?

level: juniorimportance: must knowfreq 68%

basics

~20 s

Validation compares the parsed document against the schema alone: each selected field must exist on its type, each required argument must be supplied, and each fragment must be used and acyclic. A document that fails runs no resolvers.

open as a page

What do the @skip and @include directives do in a GraphQL document?

level: juniorimportance: must knowfreq 63%

basics

~20 s

They let the client decide at request time whether part of its own selection is sent. @include(if:) keeps a selection only when its boolean is true; @skip(if:) drops it when true. An excluded selection is simply absent from the response.

open as a page

What is fragment colocation in a GraphQL client, and what problem does it solve?

level: juniorimportance: must knowfreq 58%

basics

~10 s

Fragment colocation is a client convention: every view declares the fields it needs as its own GraphQL fragment, stored beside that view, and a parent composes those fragments upward into one operation per screen.

open as a page

What is an inline fragment in a GraphQL query, and when do you need one?

level: juniorimportance: must knowfreq 71%

basics

~20 s

An inline fragment is an unnamed ... on SomeType { ... } block inside a selection set. You need one when a field returns an interface or a union and you want fields that exist only on one concrete type.

open as a page

What is a named fragment in a GraphQL document, and how do you spread one?

level: juniorimportance: must knowfreq 68%

basics

~20 s

A named fragment is a reusable selection set declared once at the top level of a document, on a type condition, and pulled into a selection with the three-dot spread. Its fields land in the response exactly as if written inline.

open as a page

What are GraphQL's three operation types, and what distinguishes them?

level: juniorimportance: must knowfreq 84%

basics

~20 s

Query, mutation and subscription. Each enters the schema through its own root type and carries a different intent: a read, a write followed by a read of the result, and a long-lived stream of events. Only the query root is required.

open as a page

What is a selection set in a GraphQL document, and when must a field carry one?

level: juniorimportance: must knowfreq 74%

basics

~20 s

A selection set is the brace-delimited list of fields a GraphQL document requests at one level. A field whose type is an object, interface or union must carry one; a field whose type is a scalar or enum must not.

open as a page

What is a variable in a GraphQL operation, and which types may it be declared as?

level: juniorimportance: must knowfreq 74%

basics

~20 s

A GraphQL variable is a named, typed placeholder declared on the operation and filled from a separate values map sent with the request. Only input types are allowed: scalars, enums, input objects, and their list or non-null wrappers.

open as a page

In a GraphQL document, what is the difference between omitting an argument and passing null?

level: middleimportance: must knowfreq 62%

basics

~10 s

Omitting an argument means no value was provided, so the schema's declared default applies. Writing null provides a value, so the default is not substituted and the server receives an explicit null.

open as a page

What does a GraphQL server do with a request's document before any resolver runs?

level: middleimportance: must knowfreq 66%

basics

~20 s

Three phases in order: parse the text into a syntax tree, validate that tree against the schema, then execute. A syntax error ends the request at parse, so nothing is validated, no resolver runs, and the response has errors and no data key.

open as a page

How does a GraphQL server choose which operation to run in a multi-operation document?

level: middleimportance: must knowfreq 61%

basics

~10 s

By the operationName the caller supplies. With exactly one operation in the document the name may be omitted; with two or more, a missing or unmatched operationName is a request error and nothing executes.

open as a page

How does a GraphQL server coerce the values in a request's variables map to their declared types?

level: middleimportance: must knowfreq 51%

basics

~20 s

Before execution the server coerces each supplied value to its declared type: scalars by strict per-type rules, enums from a string matching a member name exactly, lists item by item. A value that will not coerce is a request error.

open as a page

Which parts of a GraphQL document's text does the parser ignore?

level: juniorimportance: should knowfreq 44%

basics

~20 s

Whitespace, line breaks, a leading byte-order mark, comments running from a hash to the end of the line, and commas. Commas are ignored tokens rather than separators, so a document parses identically with all of them, some, or none.

open as a page

In GraphQL, what happens when @skip(if: true) and @include(if: true) sit on one field?

level: middleimportance: should knowfreq 45%

basics

~20 s

The field is excluded. When both directives apply to one selection, it survives only if the @skip condition is false and the @include condition is true, so a true @skip removes it whatever @include says.

open as a page

In fragment colocation, what does a fragment's type condition bind a view to?

level: middleimportance: should knowfreq 44%

basics

~20 s

To a schema type, never to the view. A fragment written on Order says only give me an Order, so any parent selecting a field of that type can spread it, and renaming the view changes nothing.

open as a page

Why do clients select __typename alongside inline fragments in GraphQL?

level: middleimportance: should knowfreq 58%

basics

~10 s

Because matched inline-fragment fields arrive flat, the response alone does not say which branch applied. __typename is a meta-field returning the concrete object type's name, so it is the discriminator a client branches on.

open as a page

Where can you spread a GraphQL fragment, and what does its type condition control?

level: middleimportance: should knowfreq 51%

basics

~20 s

A fragment may be spread into any selection set whose type could actually be the fragment's type condition - the two must share at least one possible object type. The type condition also fixes which fields the fragment is allowed to select.

open as a page

When is GraphQL's query shorthand, a bare selection set with no keyword, legal?

level: middleimportance: should knowfreq 54%

basics

~20 s

Only when the document holds exactly one operation, that operation is a query, and it declares no variables and carries no directives on the operation itself. Then both the query keyword and the operation name may be omitted.

open as a page

What does an alias do in a GraphQL query, and when do you need one?

level: middleimportance: should knowfreq 57%

basics

~20 s

An alias, written alias: field, renames the key a field appears under in the response. You need one to select the same field twice at one level with different arguments, because two selections sharing a response key must otherwise be identical.

open as a page

Why should a GraphQL caller put user-supplied values in variables rather than inline literals?

level: seniorimportance: should knowfreq 50%

basics

~10 s

Inlining makes the document text change with every value, so two runs of one operation are two different documents. That wrecks document-keyed metrics, allowlists and caches, and drops user data into logged query text.

open as a page

A shipped client's GraphQL requests all fail with a syntax error — how do you localise the fault?

level: seniorimportance: should knowfreq 30%

basics

~20 s

A syntax error proves the schema, resolvers and data stores never ran, so the fault is in the bytes the client sent. Capture that exact document text, read the error's line and column against it, and inspect how the client assembles it.

open as a page

A GraphQL document validates cleanly and still returns 388,514 rows — why didn't validation stop it?

level: seniorimportance: should knowfreq 46%

basics

~20 s

Validation compares a document only to the schema. A list field whose paging argument is optional is a legal selection however many rows come back, so nothing static can object. The bound must come from the schema and a resolver clamp.

open as a page

Where do @skip and @include fall short as a conditional mechanism in GraphQL?

level: seniorimportance: should knowfreq 39%

basics

~20 s

They gate whole selections and nothing else: no else keyword, no way to vary an argument, no condition that reads data in the same response. And a skipped field is still validated, so it cannot hide a removed one.

open as a page

In GraphQL, why do per-view queries produce a request waterfall, and what does fragment colocation change?

level: seniorimportance: should knowfreq 52%

basics

~20 s

A nested view cannot form its query until its parent's response supplies the id it needs, so round trips run in series. Colocation hoists every view's fields into one operation the screen sends before rendering.

open as a page

When a GraphQL union gains a member type, what does a client with inline fragments for only the old members receive?

level: seniorimportance: should knowfreq 44%

basics

~20 s

It receives the object with none of its branch fields — only what was selected outside the branches, which on a union is at most __typename. Nothing errors; the document stays valid and the row simply arrives empty.

open as a page

Within one GraphQL document, what do selection sets fix about over-fetching and under-fetching, and what do they not?

level: seniorimportance: should knowfreq 49%

basics

~20 s

Selection sets fix the response shape — only selected keys come back — and nesting removes dependent round-trips. They do not stop a client selecting fields nothing renders, do not shrink backend work, and cannot remove a round-trip that waits on a returned value.

open as a page

Why did a GraphQL page-size variable sent as null return every row when omitting it returned 25?

level: seniorimportance: should knowfreq 43%

basics

~20 s

Omitting a variable leaves it not provided, so the argument falls back to its schema default. Sending null provides a value, which overrides that default and reached a resolver that read null as no limit.

open as a page

What is a GraphQL block string, and how does the parser treat its indentation?

level: middleimportance: nice to knowfreq 18%

basics

~20 s

A string literal delimited by triple quotes that may span lines and contain unescaped quotes. The parser normalises line endings, strips the indentation common to every line after the first, and removes leading and trailing blank lines.

open as a page

Why must fragment spreads in a GraphQL document never form a cycle?

level: middleimportance: nice to knowfreq 24%

basics

~20 s

Spreading a fragment inlines its selections rather than calling it, so two fragments that spread each other denote a selection set with no end. The specification makes cycles a validation error, so such a document fails before execution.

open as a page

showing 1–30 of 34