This chapter follows What is GraphQL.
Every GraphQL service exposes exactly one schema. The schema does not store data or run SQL; it tells the execution engine which operations exist, which types fields return, and which arguments are legal. Clients and tools read that contract to validate documents before they hit the network.
Schema Definition Language
SDL (Schema Definition Language) is the human-readable syntax for types. A minimal service might look like this:
"""A library catalog entry."""type Book { id: ID! title: String! publishedYear: Int}
type Query { book(id: ID!): Book books: [Book!]!}Descriptions use "..." on a single line or """...""" for multiple lines. They appear in GraphiQL and in generated docs.
The schema must define a Query root type. Mutation and Subscription roots are optional but conventional for writes and live updates.
Root operation types
| Root | Purpose |
|---|---|
Query |
Read operations; fields run in parallel by default |
Mutation |
Write operations; top-level mutation fields run serially |
Subscription |
Long-lived read streams, usually over WebSockets |
Entry points are fields on these roots, not arbitrary URLs:
type Mutation { createBook(input: CreateBookInput!): Book!}
type Subscription { bookAdded: Book!}Naming roots Query, Mutation, and Subscription is convention; the spec only requires that the schema declares which object types play those roles.
Schema-first versus code-first
Teams choose how the schema file comes into existence:
| Approach | Flow | Typical stacks |
|---|---|---|
| Schema-first | Authors edit .graphql SDL, then implement resolvers by hand |
Apollo Server (SDL + resolvers map), GraphQL Yoga |
| Code-first | Types and fields are declared in code; SDL is generated at build or startup | NestJS @nestjs/graphql, Pothos, TypeGraphQL |
Neither approach changes what clients see if the emitted SDL is the same. Code-first fits teams that already live in TypeScript and want decorators or builders to stay in sync with resolvers. Schema-first fits teams that treat the SDL file as the source of truth in code review.
Directives and the type system
Built-in directives such as @deprecated(reason: "...") and @specifiedBy(url: "...") attach metadata to schema elements. Custom directives (for example @auth) extend validation or execution in server-specific ways; clients must not rely on unknown directives unless your tooling documents them.
The next chapters walk through object types, scalars, input types, and interfaces in detail. They all compose into the single schema document.
Introspection
Clients can ask the server to describe its own schema with special meta-fields:
{ __schema { queryType { name } types { name kind } }}Introspection powers GraphiQL, codegen, and federation composition. It also helps attackers map your API. Production services often disable introspection for anonymous users or expose it only on internal endpoints. Introspection answers what the schema allows; it does not reveal resolver implementation or database layout.
Next: Object types and scalars.
Check your understanding
Question 1 of 5
0 of 5 checked