0
0
GraphQLquery~15 mins

Subgraph definition in GraphQL - Deep Dive

Choose your learning style9 modes available
Overview - Subgraph definition
What is it?
A subgraph definition in GraphQL is a way to describe a part of a larger graph schema. It defines types, fields, and relationships that belong to a specific service or domain. This allows multiple teams or services to own different parts of the overall graph, which can then be combined into a single unified API.
Why it matters
Without subgraph definitions, managing large GraphQL APIs becomes difficult and chaotic. Teams would have to coordinate on one big schema, causing delays and errors. Subgraphs let teams work independently on their parts, making development faster and more scalable. This also enables a smooth way to combine multiple services into one API that clients can query easily.
Where it fits
Before learning subgraph definitions, you should understand basic GraphQL schemas and queries. After mastering subgraphs, you can learn about schema federation, which is how multiple subgraphs are combined into a single graph. Later, you might explore advanced federation features like directives and query planning.
Mental Model
Core Idea
A subgraph definition is a focused piece of a larger GraphQL schema owned by one service, describing its data and how it connects to others.
Think of it like...
Imagine a city map divided into neighborhoods. Each neighborhood map shows streets and landmarks inside it, maintained by local teams. The full city map is made by combining all neighborhood maps, letting you navigate the whole city easily.
┌─────────────┐   ┌─────────────┐   ┌─────────────┐
│ Subgraph A  │   │ Subgraph B  │   │ Subgraph C  │
│ (Service 1) │   │ (Service 2) │   │ (Service 3) │
│ Types &     │   │ Types &     │   │ Types &     │
│ Fields      │   │ Fields      │   │ Fields      │
└─────┬───────┘   └─────┬───────┘   └─────┬───────┘
      │                 │                 │
      └───────┬─────────┴─────────┬───────┘
              │                   │
        ┌─────▼───────────────────▼─────┐
        │       Federated Graph Schema    │
        │  (Unified API combining all)   │
        └────────────────────────────────┘
Build-Up - 7 Steps
1
FoundationUnderstanding GraphQL Schema Basics
🤔
Concept: Learn what a GraphQL schema is and how it defines data types and queries.
A GraphQL schema describes the shape of data you can ask for. It defines types like objects, their fields, and how clients can query them. For example, a 'User' type might have fields like 'id' and 'name'. This schema acts like a contract between client and server.
Result
You can write simple GraphQL queries and understand the data structure they return.
Understanding schemas is essential because subgraphs are just parts of these schemas owned by different services.
2
FoundationWhat is a Subgraph in GraphQL?
🤔
Concept: Introduce the idea that a subgraph is a partial schema owned by one service.
A subgraph defines a subset of the overall GraphQL schema. It includes types and fields that belong to one service or domain. For example, a 'User' service might define the 'User' type and its fields, while a 'Product' service defines 'Product' types. Each subgraph is independent but designed to fit into a bigger graph.
Result
You can identify which parts of a schema belong to which service and why splitting helps.
Knowing that schemas can be split into subgraphs helps manage complexity and team ownership.
3
IntermediateDefining Types and Fields in a Subgraph
🤔
Concept: Learn how to write types and fields inside a subgraph definition.
In a subgraph, you write GraphQL type definitions like usual, but only for the data your service owns. For example: type User @key(fields: "id") { id: ID! name: String } The '@key' directive marks the field used to identify the object across subgraphs. This helps later when combining subgraphs.
Result
You can create a valid subgraph schema that defines your service's data and keys.
Using directives like '@key' is crucial for linking data across subgraphs in federation.
4
IntermediateExtending Types Across Subgraphs
🤔Before reading on: do you think a subgraph can add fields to types defined in other subgraphs? Commit to yes or no.
Concept: Understand how subgraphs can extend types defined elsewhere to add more fields.
Subgraphs can extend types defined in other subgraphs using the 'extend' keyword. For example, if 'User' is defined in one subgraph, another can add fields: extend type User { reviews: [Review] } This allows services to add their own data to shared types without conflicts.
Result
You can write subgraphs that collaborate by extending shared types.
Knowing type extension enables modular schema design and smooth collaboration between services.
5
IntermediateUsing Directives for Federation
🤔Before reading on: do you think directives like '@key' and '@external' are optional or required for subgraph definitions? Commit to your answer.
Concept: Learn about special directives that help subgraphs work together in federation.
Federation uses directives like '@key' to mark unique identifiers, '@external' to mark fields owned by other subgraphs, and '@requires' or '@provides' to describe dependencies. These directives tell the gateway how to combine data from different subgraphs correctly.
Result
You understand how to annotate your subgraph schema for federation compatibility.
Using these directives correctly is essential for building a working federated graph.
6
AdvancedSubgraph Schema Validation and Composition
🤔Before reading on: do you think subgraph schemas are combined manually or automatically by tools? Commit to your answer.
Concept: Explore how subgraph definitions are validated and combined into a single schema.
Tools like Apollo Federation take multiple subgraph schemas and compose them into one federated schema. This process checks for conflicts, ensures keys match, and validates directives. If errors exist, composition fails, preventing broken APIs.
Result
You can troubleshoot schema composition errors and understand the importance of schema correctness.
Knowing how composition works helps prevent integration bugs and ensures smooth API operation.
7
ExpertAdvanced Subgraph Design and Performance Considerations
🤔Before reading on: do you think adding many fields to a subgraph always improves performance? Commit to yes or no.
Concept: Understand how subgraph design affects query performance and maintainability in production.
Designing subgraphs requires balancing granularity and performance. Too many small subgraphs increase network calls and complexity. Too few large subgraphs reduce modularity. Also, careful use of keys and directives affects query planning and caching. Experts optimize subgraphs to minimize latency and maximize clarity.
Result
You can design subgraphs that scale well and perform efficiently in real systems.
Understanding trade-offs in subgraph design is key to building robust, maintainable federated APIs.
Under the Hood
Subgraph definitions are GraphQL schemas annotated with federation directives. Each subgraph runs as an independent GraphQL service exposing its schema. A gateway service fetches these schemas and uses a composition algorithm to merge them into a single federated schema. This algorithm resolves type ownership, merges fields, and validates keys and references. At runtime, the gateway splits client queries into sub-queries sent to relevant subgraphs, then combines their results.
Why designed this way?
Subgraphs were designed to solve the problem of scaling GraphQL APIs across multiple teams and services. Instead of one monolithic schema, subgraphs allow decentralized ownership and independent deployment. Federation directives and composition enable these independent schemas to work together seamlessly. Alternatives like stitching schemas lacked strong ownership and had runtime inefficiencies, so federation with subgraphs became the preferred approach.
┌───────────────┐       ┌───────────────┐       ┌───────────────┐
│ Subgraph A    │       │ Subgraph B    │       │ Subgraph C    │
│ (GraphQL svc) │       │ (GraphQL svc) │       │ (GraphQL svc) │
└───────┬───────┘       └───────┬───────┘       └───────┬───────┘
        │                       │                       │
        │ Schema with directives │ Schema with directives │ Schema with directives
        └──────────────┬────────┴───────────────┬────────┘
                       │                        │
               ┌───────▼────────┐       ┌───────▼────────┐
               │ Federation     │       │ Gateway        │
               │ Composition    │──────▶│ (Query Router) │
               └────────────────┘       └────────────────┘
                       │                        │
                       │ Unified Federated Schema│
                       └────────────────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Do you think a subgraph must define all fields of a type it owns? Commit yes or no.
Common Belief:A subgraph must define every field of a type it owns completely.
Tap to reveal reality
Reality:A subgraph only defines the fields it owns or extends; other fields can be owned by other subgraphs.
Why it matters:Believing this causes duplication and conflicts in schemas, breaking federation composition.
Quick: Do you think subgraph directives like '@key' are optional for federation? Commit yes or no.
Common Belief:Directives like '@key' are optional and only for documentation.
Tap to reveal reality
Reality:These directives are required for federation to identify and link entities across subgraphs.
Why it matters:Missing directives cause runtime errors and prevent proper query resolution.
Quick: Do you think subgraphs can be combined manually without tools? Commit yes or no.
Common Belief:You can manually merge subgraph schemas without special tools.
Tap to reveal reality
Reality:Manual merging is error-prone; federation tools automate composition and validation.
Why it matters:Manual merging leads to subtle bugs and inconsistent APIs.
Quick: Do you think more subgraphs always mean better modularity and performance? Commit yes or no.
Common Belief:Splitting into many small subgraphs always improves modularity and performance.
Tap to reveal reality
Reality:Too many subgraphs increase network overhead and complexity, hurting performance.
Why it matters:Over-splitting causes slower queries and harder maintenance.
Expert Zone
1
Subgraphs can share ownership of types by carefully coordinating '@key' fields and extensions, enabling flexible data ownership models.
2
The choice of which fields to mark as '@external' affects query planning and can optimize data fetching across services.
3
Schema composition errors often stem from subtle mismatches in key fields or type definitions that are hard to spot without deep schema inspection.
When NOT to use
Subgraph definitions and federation are not ideal for very small APIs or when all data is owned by a single service. In those cases, a monolithic GraphQL schema is simpler and more efficient. Also, if services cannot coordinate schema changes or use federation directives properly, schema stitching or separate APIs might be better alternatives.
Production Patterns
In production, teams define subgraphs per domain or microservice, each with clear ownership. They use CI pipelines to validate subgraph schemas and composition before deployment. The gateway caches federated schemas and query plans for performance. Monitoring tools track query latency across subgraphs to identify bottlenecks. Incremental adoption allows migrating parts of a monolith to subgraphs gradually.
Connections
Microservices Architecture
Subgraphs map directly to microservices owning specific data domains.
Understanding microservices helps grasp why subgraphs isolate schema parts and how independent teams manage them.
Modular Programming
Subgraph definitions embody modular design by separating concerns into distinct schema modules.
Knowing modular programming principles clarifies why splitting schemas improves maintainability and scalability.
Distributed Systems
Subgraphs run as distributed services that must coordinate to serve unified queries.
Recognizing distributed system challenges like latency and consistency helps understand federation's design trade-offs.
Common Pitfalls
#1Defining the same type with conflicting fields in multiple subgraphs.
Wrong approach:type User { id: ID! name: String } // In another subgraph type User { id: ID! email: String name: Int # Conflict: different type }
Correct approach:type User @key(fields: "id") { id: ID! name: String } // In another subgraph extend type User @key(fields: "id") { id: ID! @external email: String }
Root cause:Misunderstanding that types must be defined once and extended elsewhere, not redefined with conflicting fields.
#2Omitting '@key' directive on entity types in subgraphs.
Wrong approach:type Product { sku: String! name: String }
Correct approach:type Product @key(fields: "sku") { sku: String! name: String }
Root cause:Not realizing '@key' is required to identify entities across subgraphs for federation.
#3Marking fields as '@external' without matching '@key' fields.
Wrong approach:extend type User { email: String @external }
Correct approach:extend type User @key(fields: "id") { id: ID! @external email: String @external }
Root cause:Failing to declare the key fields on extended types causes federation to lose track of entity identity.
Key Takeaways
A subgraph definition is a partial GraphQL schema owned by one service, describing its data and how it connects to others.
Subgraphs use special directives like '@key' and '@external' to enable federation and link data across services.
Subgraph schemas are composed automatically by tools to form a unified federated graph, ensuring consistency and correctness.
Designing subgraphs requires balancing modularity with performance to build scalable and maintainable APIs.
Understanding subgraphs connects deeply with concepts in microservices, modular programming, and distributed systems.