01 / 10

What is GraphQL schema?

Difficulty: 5/10
type definitions, SDL, schema stitching

In GraphQL, a schema is the backbone of your API—it defines the structure, functionality, and types of data that clients can query, mutate, or subscribe to. The schema acts as a contract between the client and server, ensuring that both parties understand what data is available, how it can be manipulated, and the relationships between various data types.

  1. 1

    The schema is made up of types, which describe the shape of data.

  2. 2

    Fields within types specify what data can be requested and returned.

  3. 3

    The schema is typically written in Schema Definition Language (SDL), which is a syntax designed specifically for defining GraphQL schemas.

The GraphQL schema is the foundation of every GraphQL API. It serves as the authoritative source of truth that defines what data can be queried, what operations can be performed, and the relationships between different types. Written in the GraphQL Schema Definition Language (SDL), the schema provides a clear, self-documenting contract that enables clients to understand exactly what the API offers. Unlike REST, where documentation is often separate, the GraphQL schema itself is the documentation—tools can automatically generate documentation, perform validation, and enable powerful IDE integrations like autocomplete and type checking.

Basic GraphQL Schema Example
Core Components of a GraphQL Schema
  1. 1

    Root Operation Types: The entry points to the schema. Every GraphQL schema must define at least a Query type, and may optionally define Mutation and Subscription types. These define the operations clients can perform.

  2. 2

    Object Types: The fundamental building blocks representing real-world entities. Each object type has fields, and each field has a type. Fields can be scalar (String, Int, Boolean, Float, ID) or other object types, enabling complex nested queries.

  3. 3

    Scalar Types: Primitive types that represent leaf values. GraphQL includes five built-in scalars: Int, Float, String, Boolean, ID. Custom scalars can be defined for specialized needs like Date or JSON.

  4. 4

    Input Types: Special object types used exclusively for mutation arguments. Input types cannot contain fields that are other object types—they can only contain scalars, enums, or other input types.

  5. 5

    Enums: A restricted list of allowed string values, useful for status fields or categorization.

  6. 6

    Interfaces: Abstract types that define a set of fields that must be implemented by any object type that implements the interface. Enables polymorphic queries.

  7. 7

    Unions: Similar to interfaces but without shared fields. A union type can be one of several object types, useful for search results or heterogeneous collections.

The GraphQL Schema Definition Language (SDL) uses a concise, readable syntax. Types are defined with the type keyword, fields are listed with their types and nullability markers (! indicates non-null, [] denotes lists). Arguments can be specified for fields. The type Query definition is special—it defines the entry point for all read operations. The type Mutation follows the same pattern but for write operations. This declarative syntax makes schemas easy to write, review, and version.

Nullability and List Syntax
Schema Evolution Best Practices
  1. 1

    Backward Compatibility: Adding new fields is safe; removing fields is breaking. Mark deprecated fields with @deprecated directive rather than removing them.

  2. 2

    Nullability: Be conservative with ! (non-null). Adding a non-null field to an existing type breaks existing queries that don't request that field.

  3. 3

    Input Types: Prefer input types over multiple scalar arguments for mutations, making them easier to extend.

  4. 4

    Versioning: Unlike REST, GraphQL APIs typically don't use version numbers. Instead, evolve the schema in a backward-compatible way.

  5. 5

    Tooling: Use schema linters to enforce consistency and catch breaking changes before deployment.

In large organizations, a single GraphQL schema may be composed from multiple services. Apollo Federation allows multiple GraphQL services (subgraphs) to be composed into a single unified schema. Each subgraph defines its part of the schema, and a gateway stitches them together. This enables team autonomy while presenting a single API to clients. The schema becomes a distributed contract across services, requiring careful coordination of type definitions and reference resolvers.

Scenario Questions

0-2 years experience

  1. 1We need to add a new field to an existing GraphQL type for a small feature. How would you update the schema and make sure the client can query it without breaking existing queries?
  2. 2If a client asks for a field that isn’t defined in the schema, what does the GraphQL server return, and how would you handle that in a simple Express setup?
  3. 3You have a schema file written in SDL. Walk me through the steps you’d take to expose it via Apollo Server.

2-5 years experience

  1. 1During a sprint we introduced a new mutation, but the client started receiving 'field not found' errors for an existing query. How would you debug the schema change to find the root cause?
  2. 2Explain the trade‑offs between putting business logic in resolvers versus describing it in the schema with directives. When would you choose one over the other?
  3. 3Our team wants to split a large schema into multiple modules. What considerations do you keep in mind to keep type relationships and tooling working?

5-8 years experience

  1. 1We’re planning to adopt GraphQL federation across several microservices. How does the shared schema evolve, and what patterns do you use to avoid breaking downstream services?
  2. 2A high‑traffic query is causing performance issues because the schema allows deeply nested selections. How would you mitigate this at the schema level?
  3. 3When versioning a GraphQL API, what strategies do you employ in the schema to support both old and new clients without duplicating types?

8+ years experience

  1. 1Our organization is migrating from a monolithic REST API to a GraphQL gateway that stitches multiple legacy schemas. What architectural decisions around the schema design help maintain backward compatibility and operational stability?
  2. 2Describe how you would set up a schema governance process across several product teams to manage breaking changes, deprecations, and documentation at scale.
  3. 3If you need to expose a GraphQL schema to external partners while keeping internal fields private, how would you design the schema and the access control layer to enforce this separation?

Follow-up Questions

  • What happens if you forget to add a resolver for a newly added field?
  • How would you communicate a breaking schema change to downstream teams?
  • Can you give an example of using a custom directive in the schema?
Share

Share via WhatsApp, X, Facebook, LinkedIn or copy link. Open Graph preview enabled.