skip to content

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

level: middleimportance: should knowfreq 54%

answer

  1. A document that is only braces
  2. Legal only when the operation stands alone
  3. Queries only, never a write
  4. Nowhere left to put variable definitions
  5. Unnamed means unattributable in metrics

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.

solid answer

~50 s

The shorthand form is a document that is nothing but a selection set — `{ clinician(id: "c-3319") { fullName } }`. The specification permits it only when the document contains a single operation, that operation is a query, and it defines no variables and carries no directives on the operation. A mutation or subscription can never use it, because the keyword is the only syntax that says which operation type you meant, and a bare selection set is defined to mean a query. A separate validation rule, lone anonymous operation, adds that if any operation in a document is anonymous it must be the only operation there — so adding a second operation forces the keyword and a name onto both. Shorthand is right in an explorer and a liability in application code, since an anonymous operation cannot be selected by name and arrives nameless in server-side metrics.

code

graphql · 9 lines
graphql
{
  clinician(id: "c-3319") {
    fullName
    appointmentsToday {
      startsAt
      patient { initials }
    }
  }
}

go deeper

for a junior

Recognise a bare braces-only document as a query with its keyword and name omitted, and know that it is what an explorer or a hand-typed request usually looks like.

for a middle

State every condition precisely — one operation, of query type, no variable definitions, no directives on the operation — and explain why the last two follow from there being nowhere to write them.

for a senior

Argue the operational case for banning shorthand in application code: anonymous operations cannot be selected by name and cannot be attributed in metrics, while keeping it perfectly acceptable for exploration.

for a principal

Own it as a standard. A lint rule demanding a keyword and a unique name on every shipped operation is cheap now and is the precondition for per-operation budgets and any document-registry workflow later.

## What the shorthand actually is The shorthand form is a document that consists of nothing but a selection set: ```graphql { clinician(id: "c-3319") { fullName appointmentsToday { startsAt } } } ``` There is no `query` keyword and no operation name. This is not a special dialect; the specification defines it as an ordinary query operation with two pieces of syntax elided, and the parser produces exactly the same operation definition it would have produced from `query { ... }`. ## The exact conditions The shorthand is legal only when all of the following hold: 1. The document contains **one** operation. Not one query alongside a mutation — one operation, full stop. 2. That operation is a **query**. Never a mutation, never a subscription. 3. It defines **no variables**. 4. It carries **no directives on the operation itself**. Candidates routinely give condition 1 and stop. Conditions 3 and 4 are the ones that separate someone who has read the grammar from someone who has only seen the shorthand in an explorer. The reason for them is mechanical rather than philosophical: variable definitions and operation directives are written in the syntactic slot between the operation name and the selection set, and once you delete the keyword and the name there is nowhere left to put them. `($id: ID!) { ... }` is not a legal document. Condition 2 has the same character. The keyword is the *only* thing in the syntax that says which operation type you meant, so a bare selection set has to mean something by default, and the specification says it means a query. There is consequently no shorthand for a write. ## The neighbouring rule: lone anonymous operation Shorthand is one way to end up with an anonymous operation, but not the only one: `query { ... }` — keyword, no name — is anonymous too. A separate validation rule governs all anonymous operations, however they were written. If a document contains an anonymous operation, that operation must be the only operation in the document. So this document is invalid: ```graphql { clinician(id: "c-3319") { fullName } } query ClinicianLoad($id: ID!) { clinician(id: $id) { appointmentCount } } ``` It fails validation before anything executes, and the response carries an `errors` entry with no `data` key. Note what the rule does *not* say: it is not 'at most one anonymous operation'. One anonymous operation plus one named operation is just as invalid as two anonymous ones, because the anonymous one is no longer alone. Fragment definitions are a common source of confusion here and the answer is reassuring: a fragment definition is a top-level definition but it is not an operation, so a document holding one anonymous query and three fragment definitions is fine. ## Why it is a liability in an application Shorthand is what an explorer hands you, what a bug report pastes, and what a curl one-liner uses. In all three settings it is exactly right — you have one operation, you are typing it by hand, and ceremony would be noise. In application code it costs you two things that are hard to recover later. First, **selectability**. An anonymous operation cannot be picked out by name, so the moment a build step wants to bundle several documents together, or a client wants to send one document containing more than one operation, every anonymous operation has to be rewritten. Second, and more expensively, **attribution**. Server-side metrics, logs and traces key on the operation name. A fleet of anonymous operations arrives at the server as an undifferentiated stream: every request is nameless, so per-operation latency, per-operation error rate and per-operation call volume all collapse into one bucket. When a single expensive read starts timing out under peak load, a nameless bucket tells you that *something* is slow and nothing else. The usual remedy is a lint rule in the client repository that requires every operation to carry the keyword and a unique name. Note that this is a **convention** enforced by tooling; the specification requires operation names to be unique only within a document, and does not require them at all when the document holds one operation. Adopting the stricter rule early is cheap; retrofitting it across a large client codebase, after the metrics you needed were already lost, is not.

  • Why can a mutation never be written in the shorthand form?
    Because the shorthand omits the operation keyword, and the keyword is the only syntax that distinguishes a mutation from a query. A bare selection set has to mean something by default, and the specification defines it to be a query, so there is nothing left to express a write with. The same reasoning excludes subscriptions.
  • A document contains one anonymous query and one named query. What does the server do?
    It rejects the document at validation, before anything executes, under the lone-anonymous-operation rule: a document containing an anonymous operation must contain no other operation. Note the rule is not 'at most one anonymous operation' — one anonymous plus one named is just as invalid as two anonymous ones. The response carries an `errors` entry and no `data` key.
  • Can a shorthand query still use arguments, and can fragment definitions sit in the same document?
    Yes to both. The restrictions apply to the operation definition: no variable definitions and no directives on the operation. Argument values written as literals are unaffected. A fragment definition is a top-level definition but not an operation, so a document holding one anonymous query and several fragment definitions still satisfies the single-operation condition.

Shorthand is the single order you can shout across a counter. The moment there are two orders in the queue, everybody needs a name written on the cup.

saying these in an interview costs you the question

  • Says the shorthand form works for mutations too
  • Thinks shorthand only means omitting the operation name
  • Believes a document may hold several anonymous operations
  • Claims a shorthand operation can declare variables
  • Counts fragment definitions as extra operations
  • Treats shorthand as fine for production client code

context