skip to content

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