GraphQL
A typed query language where the client asks for exactly the fields it needs, backed by a schema and resolver functions. Interviewers ask because it moves control of response shape to the client and creates a fresh set of performance and caching problems in exchange.
on this pageshowhide
guide
overview
~2 minGraphQL is a typed query language for APIs: a server publishes a schema, and each client sends a document naming exactly the fields it wants back. Interviewers probe it because that one shift — the client, not the server, decides the shape of every response — hands back to the server problems the REST world had long since settled: fetch amplification, HTTP caching, rate limiting, error reporting and access control. A strong answer knows which layer owns each of those problems now, and which parts of "GraphQL" come from the specification rather than from conventions the ecosystem agreed on later. The hub follows the contract from definition to production. [Type System & SDL](/topics/proto-graphql-schema-sdl) declares what can be asked, [Operations & Documents](/topics/proto-graphql-operations) is what a client actually sends, and [Execution & Resolvers](/topics/proto-graphql-resolvers) turns a validated document into data. Two consequences of per-field execution come up in nearly every round: [Batching & the N+1 Problem](/topics/proto-graphql-dataloader-n1) and [Errors & Null Propagation](/topics/proto-graphql-errors-nullability). [Pagination & Object Identity](/topics/proto-graphql-pagination-identity) and [Schema Design & Evolution](/topics/proto-graphql-schema-design) cover the conventions and judgement layered on the bare type system. Running one endpoint in public is the business of [Caching & Persisted Queries](/topics/proto-graphql-caching-persisted), [Security & Abuse Control](/topics/proto-graphql-security) and [Transports & Subscriptions](/topics/proto-graphql-transports); seeing inside it is [Tooling & Observability](/topics/proto-graphql-tooling-observability); and splitting one graph across many services is [Federation & Composition](/topics/proto-graphql-federation). Junior rounds check the vocabulary: what `!` means, the three operation types, fragments, what a resolver is handed. Senior and staff rounds turn into trade-off conversations — strict nullability against resilience, batching against joins, persisted documents against open queries, a federated graph against a single server — and production stories in which a green 200 hid a failure. Learn the type system and the document first, then execution. N+1, null propagation and schema evolution all follow from those three, and every operational section builds on them.
primer
### The schema is the contract Everything starts from a typed schema: object types, their fields and arguments, and the scalars at the leaves. Tools validate documents against it, servers execute against it, and tools read it through introspection to generate types, docs and mocks. Every field is nullable unless the schema says otherwise, and that single default shapes error handling, evolution and client code more than any other line in it. ### The client chooses the shape A document is a tree of selections over the schema, and the response mirrors that tree field for field. That is the selling point, and also the cost: the server no longer knows in advance what a request will ask for or how expensive it will be. Any list field can be widened, nested or aliased, so limits that REST attached to an endpoint now have to be attached to the operation. ### Execution is per field The executor walks the selection and calls a resolver for each field of each object it produces. The model is simple to implement and easy to reason about one field at a time — and it is exactly why a list of parents quietly multiplies backend calls, why batching sits in almost every production server, and why a mutation's root fields run in order while a query's need not. ### Failures are partial A GraphQL response can carry data and errors together. A failing field becomes null, and a Non-Null declaration pushes that null up to the nearest parent that can hold it. Nullability is therefore a decision about how much of a response survives one broken resolver, and an HTTP 200 says little about whether the operation worked. ### Much of "GraphQL" is convention Connections and cursors, global object ids, DataLoader, the `input`/payload mutation style, federation, the HTTP mapping and the WebSocket protocols are all defined outside the core specification, some by separate specifications. Interviewers probe whether you know where each rule comes from, because it decides what a server is obliged to do. ### One endpoint moves the operational work When every operation goes to one URL, caching, rate limiting, metrics and logging lose the key they used to hang on. The operation — its name, its document hash, its cost — becomes the new key, and persisted documents, complexity budgets and per-resolver tracing exist to make that key usable. ### Evolution without a version number Because each client names its fields, a server can add freely and retire slowly: additive change, deprecation, usage data per field and automated schema checks replace the `/v2` endpoint. What remains hard is knowing who still reads a field before you remove it.
- Schema
- The typed description of everything a GraphQL API can serve: its types, fields, arguments and the root types for query, mutation and subscription.
- SDL
- Schema Definition Language, the text syntax for declaring types, fields, directives and schema extensions; it can also be printed back from an introspection result.
- Non-Null type
- A type wrapped with a trailing !, promising the field never resolves to null. Everything else is nullable by default.
- Operation
- A query, mutation or subscription in a document, optionally named and optionally declaring variables; the unit a server executes.
- Selection set
- The braces listing which fields to fetch at one level of a document. Object, interface and union fields need one; scalar and enum fields cannot have one.
- Fragment
- A reusable or type-conditioned piece of a selection set, either named and spread, or inline to select fields of one concrete type.
- Variable
- A typed placeholder declared on an operation and supplied in a separate values map, so the document text stays fixed while inputs change.
- Resolver
- The function a server calls to produce one field's value for one parent object, given that parent, the field's arguments and per-request context.
- Introspection
- The built-in meta-fields, each named with a double-underscore prefix, that let a client query the schema itself and ask any object for its concrete type name.
- DataLoader
- A request-scoped utility, first published as a JavaScript library, that collects keys requested during execution, fetches them in one batch and memoizes each key.
- N+1 problem
- One fetch for a list of parents followed by one more fetch per parent for a child field, caused by per-field resolution over lists.
- Connection
- The Relay pagination convention: an object type wrapping edges, each holding a node and a cursor, plus a pageInfo describing the slice.
- Cursor
- An opaque string marking one edge's position in a connection; clients pass it back with after or before to request the next slice.
- Persisted query
- An operation registered with the server ahead of time, so clients send an identifier or hash instead of the full document text.
- Query complexity
- A score estimated from a document before execution, weighting fields and multiplying by requested list sizes, then compared against a budget.
- Normalized cache
- A client store that splits responses into objects keyed by type and id, so an update to one object refreshes every view that reads it.
- Field error
- An error raised while resolving one field. It lands in the errors list with a path, and the field, or a nullable ancestor, becomes null.
- Subgraph
- One service's schema in a federated graph. It owns some types and fields and can extend entities that other subgraphs define.
- Supergraph
- The composed schema a federation router plans against, built from every subgraph's schema; clients see a filtered API schema derived from it.
- Entity
- In federation, an object type marked with a key so that several subgraphs can contribute fields to it and the router can fetch it by that key.
Follow one request. A client, often using types generated from the schema and its own documents, sends an operation to the single endpoint — as a POST body, a cacheable GET, or just the hash of a persisted document. The server parses the text, validates it against the schema, and ideally reuses both results for the next identical document. Identity has already been read into the per-request context; an allowlist can refuse an unknown document before parsing, and depth and cost limits run in the gap between validation and execution. Execution then walks the selection. Each resolver receives its parent value and arguments; loaders in the context collect keys and fire one batched fetch per backend instead of one per parent. When a field fails, null takes its place and the error joins the list, climbing to the nearest nullable ancestor. The envelope that comes back — data, errors, extensions — goes over HTTP, a WebSocket or a server-sent event stream, and a normalized client cache splits it into objects keyed by identity. Federation adds one layer without changing the model: a router plans each client document into requests to several subgraphs and stitches their results into one response. Subscriptions reuse execution too, running the selection once per event for each subscriber. Tooling hangs off the same objects — traces per resolver, metrics per operation, usage per field. ```graphql type Post { id: ID! title: String! author: Author # resolved once per Post: batch it; nullable, so one failure costs one field } type Query { feed(first: Int!, after: String): PostConnection! # Relay convention, not the spec } query Feed($after: String) { # a variable keeps the text stable feed(first: 20, after: $after) { edges { node { title author { name } } } pageInfo { endCursor hasNextPage } } } ``` Three sections meet in those lines. The nullable `author` decides that a failing author lookup blanks one field rather than the post. The same field is where the N+1 problem appears and where a loader belongs. The variable keeps the document text identical from page to page, which is what lets parse caches, persisted documents and per-operation metrics recognise it.
- Type System & SDL →
The type system every other section assumes: scalars, objects, interfaces, unions, inputs and the nullability modifiers.
- Operations & Documents →
What a client sends: operations, selection sets, variables, fragments and the validation a document must pass.
- Execution & Resolvers →
How a validated document becomes data, and what a resolver receives; the root of most performance and error questions.
- Errors & Null Propagation →
Partial responses and null bubbling, where schema nullability turns into client behaviour and HTTP status stops meaning much.
- Batching & the N+1 Problem →
The most-asked performance question: why per-field execution multiplies fetches, and the request-scoped batching that removes them.
- Schema Design & Evolution →
The judgement layer: mutation shape, naming, nullability choices and how to change a schema without breaking clients.
Treating HTTP 200 as success: a GraphQL response can carry partial data and a non-empty
errorslist under the same status.Marking fields Non-Null for client convenience without asking what happens when their resolver fails — the null climbs to the parent, sometimes to all of
data.Claiming GraphQL removes over-fetching for free: per-field resolution moves the waste to the backend as N+1 fetches unless something batches them.
Keeping one DataLoader for the whole process as a cache — see Deduplication & Cache Lifetime for why it belongs to a single request.
Offering disabled introspection as the security answer: the schema still leaks through shipped clients and error messages, while depth, cost limits and allowlists do the real work.
Checking authorization on the root field only, when every other field returning the same object is another way in — see Field-Level Authorization.
Calling connections, global object ids, DataLoader or federation part of the GraphQL specification; they are conventions or separate specifications, and interviewers ask where each came from.
Interpolating values into document text instead of using variables, which defeats parse caching, persisted-document allowlists and per-operation metrics at once.
Answering a breaking change with a
/v2endpoint instead of additive change, deprecation and field-usage data showing who still reads the old field.Reporting one latency number for the whole endpoint: it blends every operation, so break metrics and traces down by operation name or document hash.
This guide describes the October 2021 edition of the GraphQL specification, the one most servers and published answers are written against; where a later edition or a working draft changes behaviour, say which you mean. Several things interviewers ask about sit outside that edition or changed around it: - **October 2021 edition** added repeatable directives, interfaces that implement other interfaces, and `@specifiedBy` for documenting custom scalars. Older servers built on the June 2018 edition may reject all three. - **GraphQL over HTTP** is a separate working draft. It introduces the `application/graphql-response+json` media type, under which status codes carry meaning, while plain `application/json` responses keep answering 200 for any well-formed request. - **Incremental delivery** (`@defer` and `@stream`) is a proposal, not part of the 2021 edition; servers that ship it differ in wire format. - **WebSocket subscriptions** have two protocols: the legacy one from `subscriptions-transport-ws` and the newer `graphql-transport-ws`. They are not wire-compatible, so both ends must negotiate the same one. - **Apollo Federation 2** replaced Federation 1's composition rules; sharing a field between subgraphs became explicit with `@shareable`, so directive questions depend on which version a team runs.
GraphQL is usually placed against two neighbours. REST over HTTP keeps what GraphQL gives up — URL-keyed caching, per-route limits and status codes that mean something — and fits resource-shaped APIs with few, predictable clients. gRPC suits service-to-service calls with a binary contract and streaming, and is rarely exposed to browsers directly. GraphQL earns its cost when many clients with different screens read overlapping data from several backends, often as a layer in front of REST or gRPC services rather than a replacement for them. Around the core, the choices you will be asked to defend come in layers. On the server there is a reference implementation in JavaScript, `graphql-js`, and mature servers in most languages, some schema-first and some code-first. On the client, lightweight fetchers send documents and read JSON, while normalized-cache clients such as Relay and Apollo Client own identity, pagination merging and cache updates. At the composition layer, schema stitching has largely given way to federation, with Apollo Federation the common reference and routers that implement it. Explorers such as GraphiQL, code generators and schema registries complete the toolchain. [Federation & Composition](/topics/proto-graphql-federation) and [Tooling & Observability](/topics/proto-graphql-tooling-observability) go deeper.
explore
- Type System & SDL38 questions
- Built-in & Custom Scalars4 questions
- Object Types & Field Arguments3 questions
- Interfaces & Unions3 questions
- Enums & Input Objects4 questions
- Nullability & List Modifiers3 questions
- Directive Definitions3 questions
- Schema Definition & Extensions4 questions
- Introspection Schema4 questions
- Schema-First & Code-First4 questions
- Schema Validity Rules3 questions
- Applying Custom Directives3 questions
- Operations & Documents34 questions
- Operation Types & Names4 questions
- Selection Sets & Aliases3 questions
- Variables & Coercion3 questions
- Named Fragments3 questions
- Inline Fragments4 questions
- Executable Directives4 questions
- Document Validation3 questions
- Document Syntax & Parsing4 questions
- Argument Values & Literals3 questions
- Fragment Colocation3 questions
- Execution & Resolvers29 questions
- Resolver Signature & Context3 questions
- Field Collection & Execution Order3 questions
- Default Field Resolution3 questions
- Value Completion3 questions
- Abstract Type Resolution3 questions
- Selection Lookahead3 questions
- Root Values & Trivial Resolvers3 questions
- Concurrent Field Resolution4 questions
- Subscription Event Execution4 questions
- Batching & the N+1 Problem19 questions
- Nested Fetch Amplification3 questions
- Request-Scoped Batch Loading3 questions
- Deduplication & Cache Lifetime3 questions
- Batch Key Design3 questions
- Batching Versus Joins4 questions
- Batch Dispatch Timing3 questions
- Caching & Persisted Queries32 questions
- The Single-Endpoint Cache Problem3 questions
- Queries over GET3 questions
- Automatic Persisted Queries3 questions
- Persisted Document Registries3 questions
- Edge & CDN Response Caching4 questions
- Cache Hints & Response TTL3 questions
- Normalized Client Caches3 questions
- Invalidation After Mutations4 questions
- Merging Paginated Cache Entries3 questions
- Parse & Validate Caching3 questions
- Federation & Composition43 questions
- One Graph, Many Services4 questions
- Subgraph Schemas & Entity Keys4 questions
- Entity Resolution4 questions
- Field Ownership Directives4 questions
- Query Planning5 questions
- Composition Conflicts4 questions
- Stitching Versus Composition4 questions
- Cross-Service Fetch Amplification3 questions
- Authorization Across Subgraphs4 questions
- Subgraph Failure & Partial Data4 questions
- Supergraph & Client Schemas3 questions
- Errors & Null Propagation28 questions
- The Response Envelope3 questions
- Request Versus Field Errors3 questions
- Error Object Shape4 questions
- Non-Null Error Bubbling3 questions
- Nullability as Blast Radius4 questions
- Errors as Data4 questions
- Reading Partial Responses3 questions
- Partial Mutation Failure4 questions
- Pagination & Object Identity30 questions
- Connections, Edges & Nodes3 questions
- Page Info & Cursors3 questions
- Forward & Backward Paging3 questions
- Cursor Encoding & Stability4 questions
- Offset Paging Trade-offs3 questions
- Global Object Identification3 questions
- Connection Total Counts4 questions
- Total Order for Cursors3 questions
- Nested Connection Paging4 questions
- Schema Design & Evolution37 questions
- Field & Type Naming3 questions
- Designing Mutations3 questions
- Nullable by Default4 questions
- Input Object Design3 questions
- Modelling Relationships4 questions
- Versionless Evolution4 questions
- Breaking-Change Classes4 questions
- Schema Checks & Registries4 questions
- Client-Shaped Schemas4 questions
- Filter & Sort Arguments4 questions
- Security & Abuse Control37 questions
- Introspection Exposure4 questions
- Depth & Breadth Limits3 questions
- Query Complexity Scoring4 questions
- Alias & Batch Amplification3 questions
- Operation Allowlists4 questions
- Field-Level Authorization5 questions
- Error Message Leakage3 questions
- CSRF & Content-Type3 questions
- Timeouts & Subscription Abuse4 questions
- Control Placement by Phase4 questions
- Transports & Subscriptions35 questions
- GraphQL over HTTP4 questions
- Media Types & Status Codes3 questions
- Incremental Delivery Transport3 questions
- Subscription Message Flow4 questions
- WebSocket Subprotocol Negotiation3 questions
- Subscriptions over SSE3 questions
- Delivery Semantics & Resume4 questions
- Scaling Subscription Fan-Out4 questions
- File Uploads3 questions
- Multi-Operation Requests4 questions
- Tooling & Observability32 questions
- Introspection-Driven Codegen4 questions
- Schema Linting4 questions
- Interactive Explorers4 questions
- Schema-Derived Mocks3 questions
- Testing Operations & Schemas3 questions
- Per-Resolver Tracing3 questions
- Metrics for One Endpoint4 questions
- Field Usage Analytics4 questions
- Per-Operation Logging3 questions
- Android Developerroleanchors this topic
- Backend Developerroleanchors this topic
- Frontend Developerroleanchors this topic
- Full Stack Developerroleanchors this topic
- GraphQLskillanchors this topic
- Java Backend Developerroleanchors this topic
- Kotlin Backend Developerroleanchors this topic
- iOS Developerroleanchors this topic
- AI Red Teamingrole
- API Designskill
- Forward Deployed Engineerrole
- Server-Side Game Developerrole
- Software Architectrole
questions
394 · 12 sectionsIn GraphQL, what does applying a custom directive to a schema field actually do at execution time?
basics
~10 sNothing by itself. GraphQL defines no execution semantics for custom directives, so an application is validated metadata the server must be programmed to find and act on. A directive nothing reads is documentation.
What does a directive definition in GraphQL SDL declare?
basics
~20 sA directive definition declares the directive's name, the arguments it accepts with their types and defaults, whether it may be applied more than once in the same place, and, mandatorily, the list of locations where it may be applied. It declares no behaviour.
In GraphQL, why is an enum value unquoted in a query document but a quoted string in the JSON response?
basics
~20 sGraphQL's own grammar has an enum-value token, so a value like STORED is written as a bare name in a document. JSON has no enum token, so the same value crosses the wire as a string holding that name.
In GraphQL SDL, what is the difference between an interface type and a union type?
basics
~20 sAn interface declares fields that every implementing object type must declare too, so a client can select those shared fields on the abstract type itself. A union declares no fields at all — it only lists which object types the value may be.
What is the __typename meta-field in GraphQL, and where can a client select it?
basics
~20 s__typename is a built-in meta-field selectable in any object, interface or union selection set. It returns the name of the concrete object type the server resolved, as a non-null String, so a client can tell which type it received.
Which literal value forms can a GraphQL argument take inline in a document?
basics
~20 sEight 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.
What does GraphQL validation check between parsing a document and executing it?
basics
~20 sValidation 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.
What do the @skip and @include directives do in a GraphQL document?
basics
~20 sThey 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.
What is fragment colocation in a GraphQL client, and what problem does it solve?
basics
~10 sFragment 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.
What is an inline fragment in a GraphQL query, and when do you need one?
basics
~20 sAn 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.
When a GraphQL field returns an interface or union, how does the server decide the concrete object type?
basics
~10 sThe schema never says which one, so the executor asks the type system at run time, once per resolved value. That hook must name exactly one object type from the abstract type's possible types.
In GraphQL execution, may sibling fields in one selection set resolve concurrently?
basics
~20 sYes. Apart from a mutation's root fields, an executor may resolve the fields of a selection set in any order, including at the same time, because that resolution is required to be side-effect free, so order cannot change the response.
What does a GraphQL server do for a schema field that has no resolver of its own?
basics
~20 sIt uses a default field resolver: it reads a member of the same name off the parent value the field above already resolved - a property, getter or map key - and returns it unchanged. It performs no I/O.
In GraphQL, are a mutation's root fields executed serially or in any order?
basics
~20 sSerially. GraphQL requires a mutation's top-level fields to run one after another in document order, so their side effects are ordered. A query's root fields are side-effect-free, so a server may run them in any order.
What arguments does a GraphQL field resolver receive, and which of them does the specification define?
basics
~20 sMost servers hand a resolver four things: the parent value, the coerced arguments, a request-scoped context and an execution info object. Only the first two come from GraphQL's specification; context and info are an ecosystem convention.
In GraphQL, how does a batched child lookup differ from fetching parents and children in one join?
basics
~20 sA join fetches parents and children in one database round trip and repeats each parent's columns on every child row. A batched loader makes two round trips: the parents, then one bulk lookup keyed by the parent ids collected during execution.
What must a DataLoader batch key satisfy for one bulk lookup to answer every key?
basics
~20 sA batch key must fully determine the value on its own, be comparable by value so the loader can deduplicate it, and differ from the other keys only along a dimension one bulk lookup can vary.
What contract must a DataLoader batch function honour between the keys it receives and the values it returns?
basics
~20 sA DataLoader batch function takes a list of keys and returns a list of values of the same length, with each value at its key's index. Absent keys get null; failed keys get an error value.
What does the DataLoader pattern's per-key cache do inside a single request?
basics
~20 sIt memoizes by key. The first load of a key starts the backend fetch; every later load of that same key in that request gets the same result with no second fetch. It deduplicates within a request rather than caching across them.
When does a DataLoader dispatch its queued keys to the batch function?
basics
~20 sNot when load is called. Each load queues its key and returns a pending result; the queue goes to the batch function only once execution can make no further progress, which may happen several times per request.
Why does returning the updated object from a GraphQL mutation refresh a normalized client cache?
basics
~20 sA normalized store keys objects by type and id, not by the operation that fetched them. When a mutation's response carries the same id with new field values, the store overwrites that entity, and every view reading it updates.
Why does a normalized client cache store one entry per argument set for a paginated list field?
basics
~20 sA cached field is stored under a key made of the field name plus the arguments it was fetched with, because different arguments mean a different answer. Each page, fetched with a different cursor argument, therefore lands in its own entry.
What does a normalized GraphQL client cache store, and how does it differ from a document cache?
basics
~20 sA normalized client cache shreds each response into individual objects stored under an identity key, usually the object's __typename plus its id, with nested objects replaced by references. A document cache instead stores a whole response under the operation plus its variables.
With a build-time persisted document registry, what does a GraphQL request carry instead of the document text?
basics
~20 sAn identifier for a document the server already holds, plus the variables. A build step extracts every operation from the client source into a manifest and publishes it ahead of the release; the shipped client carries identifiers, never query text.
Why can't an HTTP cache reuse a GraphQL response when every operation is POSTed to one URL?
basics
~20 sHTTP caches key stored responses on the request method and target URL. Every GraphQL operation is POSTed to the same path, so the discriminator — the document and its variables — sits in a body no cache reads.
In Apollo Federation, why does composition fail when two subgraphs declare the same field with different types?
basics
~20 sComposition merges the subgraph schemas into one supergraph, so every field ends up with exactly one type. Two different named types cannot both be published, so composition reports an error and produces no supergraph at all.
In a federated graph, why does the router batch entity fetches instead of one call per item?
basics
~20 sOne call per item is an N+1 across services, where each call is a full subgraph request. The router instead collects every item's key into a single _entities call carrying a list of representations, so a 143-item list costs one request.
In GraphQL, what does a client see when many services sit behind one endpoint?
basics
~20 sOne schema and one endpoint. The client sends a single operation and gets one response, and nothing in that response says which service produced which field. The split across services is a server-side arrangement the caller never sees.
What is a query plan in a federated GraphQL supergraph, and what is each step?
basics
~20 sA query plan is the ordered set of subgraph requests a federation router derives from one client document. Each step is a complete GraphQL operation sent to exactly one subgraph, and the router merges the results into a single response.
In GraphQL schema stitching, what does the gateway hold that the services do not?
basics
~20 sThe gateway holds the merge configuration: renames that resolve name collisions, plus delegation rules saying which field on one service's type is answered by calling which operation on another. The stitched services stay ordinary GraphQL servers, unaware of each other.
What entries can a single item in a GraphQL response's errors list carry, and which is required?
basics
~20 sOnly message is required, a string describing the failure. An error may also carry locations pointing into the document sent, path locating the field in the response, and extensions, a free-form map for server-specific data such as a code.
In GraphQL, what does it mean to return an expected failure as data rather than as a top-level error?
basics
~20 sIt means the schema declares the failure as its own type — a union member or an error field inside a payload — so the failure arrives under data as an ordinary selectable value instead of in the response's top-level errors list.
What happens in GraphQL when a resolver for a Non-Null field raises an error?
basics
~20 sThe field cannot hold null, so the error propagates to its parent. The parent becomes null if it is nullable; otherwise the error keeps climbing, and if every field up to the root is Non-Null, data itself becomes null.
Why can a GraphQL mutation document leave a write half-applied?
basics
~20 sA document can carry several root mutation fields. They run one after another, and nothing wraps the group in a shared transaction, so if the second one fails the first one's write has already committed and stays committed.
A GraphQL response contains both a data object and a non-empty errors list — what does that mean?
basics
~20 sExecution ran and some fields failed while others resolved. The data object holds every field that succeeded, with null in the holes; each errors entry names the field that broke via its path. Both halves are real.
What is a Relay-style connection in GraphQL, and why return edges instead of a plain list?
basics
~20 sA connection is an object type that wraps a paged list. It holds an edges list, where each edge carries one item as its node plus that item's opaque cursor, and a pageInfo object describing the slice.
Why is a GraphQL connection cursor usually base64 text, and what does calling it opaque require of a client?
basics
~20 sBase64 is a convention, not a rule: the Relay cursor connections specification only requires a cursor to serialize as a String. Encoding it discourages parsing, so a client must store the cursor and echo it back unchanged.
What do the first/after and last/before arguments select on a GraphQL connection?
basics
~10 sfirst/after pages forward: take the first N edges after a cursor. last/before pages backward: take the last N edges before a cursor. Both slice the same fixed ordering, and neither reverses it.
What do the Relay server specification's Node interface and node root field give a client?
basics
~20 sThe Node interface makes every implementing type expose a non-null ID field whose value is unique across the whole schema. The node root field takes one of those identifiers and refetches that object, whatever its concrete type is.
In a nested GraphQL connection, does first: 10 mean ten rows total or ten per parent?
basics
~20 sTen per parent. A nested connection field is resolved once for every object in the outer page, and its arguments slice that parent's own children, so an outer page of 23 with first: 10 inside can return 230 leaf rows.
Which edits to a GraphQL schema break existing clients, and which do not?
basics
~20 sRemoving or renaming a field, argument, type or enum value breaks clients, as does adding an argument or input field that is non-null with no default. Adding a new nullable field or optional argument breaks nobody.
Why is a GraphQL schema usually designed from client demand rather than from database tables?
basics
~20 sThe schema is the contract clients hold, not a view of storage. Designing it from the questions clients actually ask keeps types stable when tables change, and stops the shape of the database leaking into the API.
In a GraphQL schema, why type a list field's sort argument as an enum rather than a String?
basics
~20 sAn enum makes the set of sortable keys part of the schema. An unknown value is rejected before execution, introspection publishes the legal values, and no resolver has to defend itself against an arbitrary column name in a string.
Why do GraphQL mutations conventionally take a single `input` argument and return a payload type?
basics
~20 sNeither half is in the GraphQL specification; both are ecosystem conventions. A single input object gives clients one variable to pass and one place to add fields later. A payload object type leaves room to return more than the record you wrote.
Which name rules does the GraphQL specification enforce, and which are only convention?
basics
~20 sThe specification fixes only the character grammar - a leading letter or underscore, then letters, digits or underscores - case sensitivity, and the reservation of any name starting with two underscores. camelCase fields and PascalCase types are ecosystem habit, not rules.
How do field aliases let one GraphQL document request the same field hundreds of times?
basics
~20 sAn alias sets the key a field's value appears under in the response, so the same field can be selected many times under different keys. Each aliased selection is executed separately, multiplying the server's work.
What security controls does the GraphQL specification itself define for a server?
basics
~20 sThe GraphQL specification defines no security controls at all - only a type system, document syntax, validation rules, an execution algorithm and a response shape. Authentication, authorization, rate limiting, depth caps and cost limits are server policy.
Why can a GraphQL document nest arbitrarily deep when the schema has finitely many types?
basics
~20 sObject types can reference each other, so the type graph contains cycles. A finite schema therefore admits documents of unlimited depth: each trip round a cycle adds one selection level, and the GraphQL specification sets no depth limit.
Why does an exception thrown in a GraphQL resolver end up in the client's error message?
basics
~20 sA GraphQL server must produce a message for every error it returns, and the simplest string available is the thrown exception's own. Nothing in the specification redacts it, so driver text, file paths and internal hostnames travel straight to the caller.
Why is authorizing only the entry field of a GraphQL query not enough to protect the data behind it?
basics
~20 sA graph reaches the same object down many paths, so a check on the root field guards one entrance only. Every other schema field returning that object is another way in, and each needs its own check.
What happens to GraphQL subscription events published while a subscriber is disconnected?
basics
~10 sThey are lost. Neither the GraphQL specification nor the WebSocket subprotocols defines buffering, replay or acknowledgement, so a reconnecting client subscribes again from the present moment and is never told what it missed.
GraphQL defines no file type, so how does a client send a file with an operation?
basics
~20 sThe GraphQL specification defines no binary scalar and no file transport. Two conventions fill the gap: a multipart request that carries the operation and the bytes together, or uploading to storage separately and passing a reference back through a mutation.
Why can a GraphQL response carry HTTP 200 OK and still report that the operation failed?
basics
~20 sThe HTTP status describes the transport, not the GraphQL result. A request the server parsed and executed answers 200 even when execution produced errors, and under the legacy application/json response type the GraphQL over HTTP draft requires 200 for every well-formed request.
What does a GraphQL POST request body contain, and what is each key for?
basics
~20 sA GraphQL POST body is a JSON object with up to four keys: query, the operation document text; variables, a map of variable values; operationName, naming which operation in the document to run; and extensions, an implementation-defined map.
How does a GraphQL subscription operation reach a server that streams results as text/event-stream?
basics
~20 sThe operation travels in the HTTP request that opens the stream: a POST body carrying query and variables, or a GET with the same values as URL parameters. An event stream is one-way, so nothing can be sent upstream afterwards.
What inputs does a GraphQL typed client generator need, and what does it emit?
basics
~20 sTwo inputs: the schema, as an SDL file or as an introspection result, and the client's own operation documents. It emits, per operation, a variables type and a result type shaped by that operation's selection set.
What does an in-browser GraphQL explorer read to build its docs pane and autocomplete?
basics
~20 sAn introspection response from the same endpoint, fetched once when the tab loads. Every type, field, argument, default value and description shown in the docs pane and offered by the completion list comes from that single reply.
Why is one GraphQL endpoint's overall request latency metric not actionable?
basics
~20 sBecause every operation shares one route, so the metric blends unrelated workloads: a few-millisecond name lookup and a multi-second report land in the same series. The number tracks the traffic mix, not any operation's health.
What is a schema-derived GraphQL mock server, and where do its field values come from?
basics
~20 sA schema-derived mock is a GraphQL server built from the schema alone, with no resolvers behind it. Every field returns a value invented from its declared type - a placeholder string, a number, an enum member, a short list.
What does a schema linter flag in SDL that is still legal GraphQL?
basics
~20 sConventions the specification deliberately leaves open: a missing description, an @deprecated with no reason, a nullable item inside a list, a type no root field can reach. All of that is a valid schema; a linter objects anyway.