Vocabulary for GraphQL APIs: Schema, Resolvers, Mutations, and Subscriptions
Master core GraphQL vocabulary: schema, types, queries, mutations, subscriptions, resolvers, fragments, and the N+1 problem. Precise English for engineers building GraphQL APIs.
GraphQL has a vocabulary all its own, and it differs sharply from REST. If you describe a GraphQL API using REST words — “endpoints,” “routes,” “GET and POST” — you’ll sound out of your depth. This guide covers the core terms, the verb collocations engineers actually use, and the distinctions (query vs. mutation, field vs. type) that matter in conversation.
The mental shift: one endpoint, a typed graph
In REST, you have many endpoints, one per resource. In GraphQL, you have one endpoint and a typed schema describing everything available. The client asks for exactly the fields it needs — no more, no less.
“Instead of hitting five REST endpoints, the client sends one query to the GraphQL endpoint and asks for exactly the fields it needs in a single round trip.”
Two phrases that capture GraphQL’s selling points:
- Over-fetching — getting more data than you need (a REST problem GraphQL solves).
- Under-fetching — needing several requests to get everything (also solved).
The schema and the type system
The schema is the contract — it defines every type and operation.
- Type — a shape of data, e.g.
User,Post. - Field — a property on a type, e.g.
user.email. - Scalar — a primitive:
String,Int,Boolean,ID,Float. - Nullable vs. non-null —
Stringcan be null;String!cannot. - Enum — a fixed set of allowed values.
- Interface / union — ways to express polymorphic types.
- Input type — a type used for arguments (e.g. a mutation’s payload).
- SDL — Schema Definition Language, the syntax you write the schema in.
Collocations:
- you define a type / add a field / mark a field non-null
- the schema exposes a query
- a field resolves to a value
“We define a
Usertype with a non-nullidfield and a nullablebio. The schema exposes auser(id: ID!)query.”
Pronunciation: schema is /ˈskiːmə/ (SKEE-muh). Not “shema.” This trips up a lot of speakers.
The three operation types
GraphQL has exactly three operation types — know the difference cold:
- Query — read data. (Like GET.)
- Mutation — write/change data. (Like POST/PUT/DELETE.)
- Subscription — receive real-time updates over a persistent connection.
“We expose a
postsquery to read, acreatePostmutation to write, and apostAddedsubscription so clients get live updates.”
A common error: calling a write a “query.” In GraphQL, reads are queries, writes are mutations. If you say “I’ll write a query to update the user,” a GraphQL engineer will correct you to “mutation.”
Resolvers: where the data comes from
A resolver is the function that produces the value for a field. This is the heart of a GraphQL server.
- a resolver resolves a field
- resolvers run per field, top-down
- a resolver fetches data from a database or another service
“The
userresolver fetches the user from Postgres; theuser.postsresolver then resolves the posts. Each field has its own resolver.”
Related terms:
- Resolver chain — resolvers calling down into nested fields.
- Context — shared data (auth, loaders) passed to every resolver.
- Root resolver — the entry point (Query, Mutation, Subscription).
The N+1 problem and DataLoader
The single most-discussed GraphQL performance issue:
- N+1 problem — fetching a list of N items, then making N more queries for each item’s nested data (1 + N queries).
- Batching — combining many small fetches into one.
- DataLoader — a utility that batches and caches these fetches within a request.
“Loading 50 posts triggered 50 separate author lookups — the classic N+1 problem. We added a DataLoader to batch them into one query.”
This is a near-guaranteed interview question for GraphQL roles. Be able to define it in one sentence.
Querying: fields, arguments, fragments, variables
On the client side:
- Field selection — choosing which fields to return.
- Argument — a parameter on a field, e.g.
user(id: 5). - Variable — a
$-prefixed placeholder for dynamic values. - Fragment — a reusable set of fields.
- Alias — renaming a field in the response.
- Directive — a modifier like
@includeor@skip.
“We extract the shared fields into a fragment, pass the ID as a variable, and use a directive to conditionally include the
Errors, deprecation, and evolution
- Partial response — GraphQL can return data and errors together.
- Errors array — where field-level errors appear, alongside
data. - Deprecation — mark a field as obsolete with
@deprecated(reason: "...")rather than deleting it. - Schema evolution — adding fields is safe (additive); removing or renaming is a breaking change.
“Rather than deleting
fullName, we deprecated it with a reason and addedfirstName/lastName. Additive changes are backward-compatible; removals are breaking.”
REST → GraphQL vocabulary swap
| REST word | GraphQL word |
|---|---|
| Endpoint / route | Single endpoint + schema |
| GET | Query |
| POST / PUT / DELETE | Mutation |
| Resource | Type |
| Response field | Field (you select them) |
| Polling for updates | Subscription |
Common mistakes non-native engineers make
- Calling a write a “query.” Reads are queries; writes are mutations.
- Saying “endpoints” (plural). GraphQL has one endpoint and a schema.
- Mispronouncing “schema.” It’s SKEE-muh.
- Confusing field and type. A type is the shape (
User); a field is a property on it (email). - Saying “the API returns too much.” Use over-fetching — the precise term.
Key takeaways
- GraphQL means one endpoint, a typed schema, and clients selecting exactly the fields they need.
- The three operations are query (read), mutation (write), subscription (real-time) — never call a write a query.
- Resolvers produce field values; the famous performance trap is the N+1 problem, solved with DataLoader batching.
- Evolve schemas by deprecating, not deleting — additions are safe, removals are breaking changes.
- Drop REST words like “endpoints” and “routes”; using GraphQL’s own vocabulary is what makes you sound fluent.