Skip to content

Commit a7746e8

Browse files
sarahxsandersbenjie
authored andcommitted
docs: guide on scaling your API (#4414)
adds guide on Scaling your API, covering monoliths, schema stitching, and federation --------- Co-authored-by: Benjie <[email protected]>
1 parent 33cfafc commit a7746e8

File tree

3 files changed

+165
-0
lines changed

3 files changed

+165
-0
lines changed

cspell.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ overrides:
2929
- xlink
3030
- composability
3131
- deduplication
32+
- subschema
33+
- subschemas
3234
- NATS
35+
- Graphile
3336

3437
validateDirectives: true
3538
ignoreRegExpList:

website/pages/docs/_meta.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ const meta = {
3636
title: 'FAQ',
3737
},
3838
'going-to-production': '',
39+
'scaling-graphql': '',
3940
};
4041

4142
export default meta;
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
---
2+
title: Scaling your GraphQL API
3+
---
4+
5+
As your application grows, so does your GraphQL schema. What starts as a small,
6+
self-contained monolith may eventually need to support multiple teams, services, and
7+
domains.
8+
9+
This guide introduces three common patterns for structuring GraphQL APIs at different
10+
stages of scale: monolithic schemas, schema stitching, and federation. It also explains
11+
how these patterns relate to GraphQL.js and what tradeoffs to consider as your
12+
architecture evolves.
13+
14+
## Monolithic schemas
15+
16+
A monolithic schema is a single GraphQL schema served from a single service. All types,
17+
resolvers, and business logic are located and deployed together.
18+
19+
This is the default approach when using GraphQL.js. You define the entire schema in one
20+
place using the `GraphQLSchema` constructor and expose it through a single HTTP endpoint.
21+
22+
The following example defines a minimal schema that serves a single `hello` field:
23+
24+
```js
25+
import { GraphQLSchema, GraphQLObjectType, GraphQLString } from 'graphql';
26+
27+
const QueryType = new GraphQLObjectType({
28+
name: 'Query',
29+
fields: {
30+
hello: {
31+
type: GraphQLString,
32+
resolve: () => 'Hello from a monolithic schema!',
33+
},
34+
},
35+
});
36+
37+
export const schema = new GraphQLSchema({ query: QueryType });
38+
```
39+
40+
This structure works well for small to medium projects, especially when a single team owns the entire
41+
graph. It's simple to test, deploy, and reason about. As long as the schema remains manageable
42+
in size and scope, there's often no need to introduce additional architectural complexity.
43+
44+
## Schema stitching
45+
46+
As your application evolves, you may want to split your schema across modules or services while
47+
still presenting a unified graph to clients. Schema stitching allows you to do this by merging
48+
multiple schemas into one executable schema at runtime.
49+
50+
GraphQL.js does not include stitching capabilities directly, but the
51+
[`@graphql-tools/stitch`](https://the-guild.dev/graphql/stitching/docs/approaches) package
52+
implements stitching features on top of GraphQL.js primitives.
53+
54+
The following example stitches two subschemas into a single stitched schema:
55+
56+
```js
57+
import { stitchSchemas } from '@graphql-tools/stitch';
58+
59+
export const schema = stitchSchemas({
60+
subschemas: [
61+
{ schema: userSchema },
62+
{ schema: productSchema },
63+
],
64+
});
65+
```
66+
67+
Each subschema can be developed and deployed independently. The stitched schema handles query delegation,
68+
merging, and resolution across them.
69+
70+
Stitching is useful when:
71+
72+
- Integrating existing GraphQL services behind a single endpoint
73+
- Incrementally breaking up a monolithic schema
74+
- Creating internal-only aggregators
75+
76+
However, stitching can add runtime complexity and often requires manual conflict resolution for
77+
overlapping types or fields.
78+
79+
## Federation
80+
81+
Federation is a distributed architecture that composes a single GraphQL schema from multiple independently
82+
developed services, known as subgraphs. Each subgraph owns a portion of the schema and is responsible
83+
for defining and resolving its fields.
84+
85+
Unlike schema stitching, federation is designed for large organizations where teams need autonomy over
86+
their part of the schema and services must be deployed independently.
87+
88+
Federation introduces a set of conventions to coordinate between services. For example:
89+
90+
- `@key` declares how an entity is identified across subgraphs
91+
- `@external`, `@requires`, and `@provides` describe field-level dependencies across service boundaries
92+
93+
Rather than merging schemas at runtime, federation uses a composition step to build the final schema.
94+
A dedicated gateway routes queries to subgraphs and resolves shared entities.
95+
96+
GraphQL.js does not provide built-in support for federation. To implement a federated subgraph using
97+
GraphQL.js, you'll need to:
98+
99+
- Add custom directives to the schema
100+
- Implement resolvers for reference types
101+
- Output a schema that conforms to a federation-compliant format
102+
103+
Most federation tooling today is based on
104+
[Apollo Federation](https://www.apollographql.com/docs/graphos/schema-design/federated-schemas/federation).
105+
However, other approaches exist:
106+
107+
- [GraphQL Mesh](https://the-guild.dev/graphql/mesh) allows federation-like composition across
108+
services using plugins.
109+
- Custom gateways and tooling can be implemented using GraphQL.js or other frameworks.
110+
- The [GraphQL Composite Schemas WG](https://github.com/graphql/composite-schemas-wg/) (formed of Apollo, ChilliCream, The Guild, Netflix, Graphile and many more) are working on an open specification for the next generation of GraphQL Federation
111+
112+
Federation is most useful when schema ownership is distributed and teams need to evolve their subgraphs
113+
independently under a shared contract.
114+
115+
## Choosing the right architecture
116+
117+
The best structure for your GraphQL API depends on your team size, deployment model, and how your
118+
schema is expected to grow.
119+
120+
| Pattern | Best for | GraphQL.js support | Tooling required |
121+
|---|---|---|---|
122+
| Monolith | Default choice for most projects; simpler, faster, easier to reason about | Built-in | None |
123+
| Schema stitching | Aggregating services you control | External tooling required | `@graphql-tools/stitch`
124+
| Federation | Large enterprises; many teams contributing to a distributed graph independently | Manual implementation | Significant tooling and infrastructure |
125+
126+
## Migration paths
127+
128+
Architectural patterns aren't mutually exclusive. In many cases, teams evolve from one approach to another
129+
over time.
130+
131+
### Monolith to schema stitching
132+
133+
Schema stitching can act as a bridge when breaking apart a monolithic schema. Teams can extract parts
134+
of the schema into standalone services while maintaining a unified entry point. This allows for gradual
135+
refactoring without requiring a full rewrite.
136+
137+
### Stitching to federation
138+
139+
Federation formalizes ownership boundaries and removes the need to manually coordinate overlapping types.
140+
If schema stitching becomes difficult to maintain, federation can offer better scalability and governance.
141+
142+
### Starting with federation
143+
144+
Some teams choose to adopt federation early, particularly in large organizations with multiple backend
145+
domains and team boundaries already in place. This can work well if you have the infrastructure and
146+
experience to support it.
147+
148+
## Guidelines
149+
150+
The following guidelines can help you choose and evolve your architecture over time:
151+
152+
- Start simple. If you're building a new API, a monolithic schema is usually the right place
153+
to begin. It's easier to reason about, test, and iterate on.
154+
- Split only when needed. Don't reach for composition tools prematurely. Schema stitching or federation
155+
should be introduced in response to real organizational or scalability needs.
156+
- Favor clarity over flexibility. Stitching and federation add power, but they also increase complexity.
157+
Make sure your team has the operational maturity to support the tooling and patterns involved.
158+
- Define ownership boundaries. Federation is most useful when teams need clear control over parts of
159+
the schema. Without strong ownership models, a federated graph can become harder to manage.
160+
- Consider alternatives. Not all use cases need stitching or federation. Sometimes, versioning, modular
161+
schema design, or schema delegation patterns within a monolith are sufficient.

0 commit comments

Comments
 (0)