-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Learn GraphQL federation #1826
Open
kamilkisiela
wants to merge
11
commits into
graphql:source
Choose a base branch
from
kamilkisiela:federation
base: source
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Learn GraphQL federation #1826
Changes from 9 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
9ccaeb5
Learn GraphQL federation
kamilkisiela 1793df4
prettier
kamilkisiela bd68e63
fix
kamilkisiela f0e12e5
I can do this all day long...
kamilkisiela 3dd1d8d
told you...
kamilkisiela 7664070
Update src/pages/learn/federation.mdx
kamilkisiela 7d2f8cd
Merge branch 'source' into federation
benjie 2655171
Thank you @andrewicarlson
kamilkisiela c31a7aa
Apply feedback
kamilkisiela f35b768
Apply Benjie's feedback
kamilkisiela a0e50d6
Make it clear you do not need federation on day 1
kamilkisiela File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,4 +22,5 @@ export default { | |
"global-object-identification": "", | ||
caching: "", | ||
security: "", | ||
federation: "", | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,274 @@ | ||
--- | ||
sidebarTitle: Federation | ||
--- | ||
|
||
import { Tabs } from 'nextra/components' | ||
|
||
# GraphQL Federation | ||
|
||
As applications grow more complex, traditional monolithic approaches often fall short. At scale, | ||
monolithic architectures can become cumbersome, brittle, and increasingly hard to test and validate. | ||
This has led to a rise in the adoption of new patterns like distributed systems and microservices. | ||
In some ways, GraphQL Federation is like microservices for GraphQL – an architectural pattern that | ||
has found particular resonance in the GraphQL ecosystem. | ||
|
||
GraphQL Federation gained widespread adoption after | ||
[Apollo GraphQL introduced Apollo Federation in 2019](https://www.apollographql.com/blog/apollo-federation-f260cf525d21). | ||
Their implementation has become a reference point for the GraphQL community, helping establish | ||
federation as a standard architectural pattern for building a distributed graph in the GraphQL | ||
ecosystem. | ||
|
||
With more companies and developers seeing the benefits of building a distributed graph with | ||
federation, the GraphQL ecosystem is now moving towards standardization of federation patterns. The | ||
GraphQL Foundation's | ||
[Composite Schema Working Group](https://github.com/graphql/composite-schemas-wg), which includes | ||
engineers from various organizations across the industry including | ||
[Apollo GraphQL](https://apollographql.com), [ChilliCream](https://chillicream.com/), | ||
[Graphile](https://www.graphile.org/), [Hasura](https://hasura.io/), | ||
[Netflix](https://www.netflix.com/) and [The Guild](https://the-guild.dev), is actively working on | ||
creating | ||
[an official specification for GraphQL Federation](https://github.com/graphql/composite-schemas-spec). | ||
This effort aims to standardize how GraphQL services can be composed and executed across distributed | ||
systems, while ensuring room for innovation and different implementations. | ||
|
||
## What is federation? | ||
|
||
Architecturally, federation is an approach to organizing and managing distributed systems. At its | ||
core, federation allows autonomous components to work together while maintaining their independence. | ||
Think of it like a federal government system: individual states maintain their sovereignty while | ||
cooperating under a central authority for shared concerns. | ||
|
||
In software architecture, federation enables organizations to: | ||
|
||
- Distribute responsibility across independent teams | ||
- Scale different components independently | ||
- Maintain clear boundaries between different domains | ||
- Enable autonomous development and deployment | ||
- Reduce single points of failure | ||
|
||
Think of the "Login with Google" or "Login with Facebook" buttons you see on websites. This is | ||
federation in action: you can use your Google or Facebook account to log into many different | ||
websites, even though each company manages their own login system separately. | ||
|
||
## What Is Federated GraphQL? | ||
|
||
GraphQL Federation applies those principles to GraphQL APIs. It enables organizations to build a | ||
unified GraphQL schema from multiple independent services (most often called subgraphs), each | ||
responsible for its portion of the application's data graph. | ||
|
||
Consider an e-commerce platform: You might have separate teams managing products, user accounts, and | ||
order processing. With GraphQL Federation, each team can: | ||
|
||
- Define their own GraphQL schema | ||
- Deploy and scale their service independently | ||
- Contribute to a unified GraphQL API without tight coupling | ||
- Maintain ownership of their domain-specific logic | ||
|
||
The magic happens through a federated gateway that acts as the central coordinator, composing these | ||
separate schemas into a unified schema that clients can query. | ||
|
||
## How Federation Works in GraphQL | ||
|
||
The federation process involves several key components: | ||
|
||
- **Subgraphs**: Individual services that define their own GraphQL schemas and resolvers | ||
- **Gateway**: A specialized service that sits between clients and your federated services | ||
- **Schema composition**: The process of merging schemas while resolving references between them, | ||
often handled by schema registries. | ||
|
||
<Tabs items={['Products subgraph', 'Orders subgraph', 'Users subgraph']}> <Tabs.Tab> | ||
|
||
```graphql | ||
type Product @key(fields: "id") { | ||
id: ID! | ||
title: String! | ||
price: Float! | ||
inStock: Boolean! | ||
} | ||
``` | ||
|
||
</Tabs.Tab> <Tabs.Tab> | ||
|
||
```graphql | ||
type Order @key(fields: "id") { | ||
id: ID! | ||
products: [Product!]! | ||
total: Float! | ||
} | ||
|
||
type Product { | ||
id: ID! | ||
} | ||
``` | ||
|
||
</Tabs.Tab> <Tabs.Tab> | ||
|
||
```graphql | ||
type Query { | ||
user(id: ID!): User | ||
} | ||
|
||
type User { | ||
id: ID! | ||
name: String! | ||
email: String | ||
orders: [Order!]! | ||
} | ||
|
||
type Order { | ||
id: ID! | ||
} | ||
``` | ||
|
||
</Tabs.Tab> </Tabs> | ||
|
||
### Schema Composition | ||
|
||
Let's break down schema composition in GraphQL federation with more detail and examples. Schema | ||
composition is the process where multiple subgraph schemas are combined into one unified schema. | ||
It's more complex than simply merging schemas together, though, because it needs to handle | ||
relationships, detect incompatibilities, and ensure types are properly connected across services and | ||
subgraphs. | ||
|
||
Based on the examples we provided before, here's the unified schema GraphQL clients will see and can | ||
query: | ||
|
||
```graphql | ||
type Query { | ||
user(id: ID!): User | ||
} | ||
|
||
type User { | ||
id: ID! | ||
name: String! | ||
email: String | ||
orders: [Order!]! | ||
} | ||
|
||
type Order { | ||
id: ID! | ||
products: [Product!]! | ||
total: Float! | ||
} | ||
|
||
type Product { | ||
id: ID! | ||
title: String! | ||
price: Float! | ||
inStock: Boolean! | ||
} | ||
``` | ||
|
||
This unified schema combines types and fields from all three subgraphs (Users, Orders, and | ||
Products), allowing clients to seamlessly query across these domains. | ||
|
||
### Gateway | ||
|
||
The federation gateway is the entry point to your distributed data graph. It presents a unified | ||
GraphQL endpoint to clients and handles the complexity of routing queries to the appropriate | ||
subgraphs and assembling the results, and often provides caching and performance optimizations. | ||
|
||
```mermaid | ||
graph TD | ||
Client --> FederationGateway | ||
FederationGateway --> UsersService | ||
FederationGateway --> OrdersService | ||
FederationGateway --> ProductsService | ||
|
||
Client[Client] | ||
FederationGateway[Gateway] | ||
UsersService[Users Service] | ||
OrdersService[Orders Service] | ||
ProductsService[Products Service] | ||
``` | ||
|
||
Take the following query as an example: | ||
|
||
```graphql | ||
query { | ||
user(id: "123") { | ||
# Resolved by Users subgraph | ||
name | ||
orders { | ||
# Resolved by Orders subgraph | ||
id | ||
products { | ||
# Resolved by Products subgraph | ||
title | ||
price | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
The gateway will route parts of the query to the appropriate subgraphs, collect the results, and | ||
assemble them into a single response that the client can consume. | ||
|
||
## Benefits of GraphQL Federation | ||
|
||
### Domain-Driven Development | ||
|
||
Teams can work independently on their services while contributing to a cohesive API. This autonomy | ||
accelerates development and reduces coordination overhead. | ||
|
||
### Service Integrity Protection | ||
|
||
The schema composition step verifies integration between services by ensuring that changes in | ||
individual subgraphs do not conflict with other subgraphs. | ||
|
||
### Scalability and Performance | ||
|
||
Subgraphs and services can be scaled independently based on their specific requirements. The product | ||
catalog might need different scaling characteristics than the order processing system. | ||
|
||
### Single, Unified API | ||
|
||
Thanks to GraphQL, clients get a single endpoint with unified schema spanning multiple subgraphs. | ||
The complexity of distributed systems is hidden. The gateway ensures every query reaches its | ||
destination and returns with the right data. | ||
|
||
## Is GraphQL Federation Right for You? | ||
|
||
GraphQL Federation aligns naturally with Domain Driven Design (DDD) principles by allowing teams to | ||
maintain clear boundaries around their domains, while maintaining explicit integration points | ||
through the GraphQL schema. It is particularly valuable for organizations where multiple teams need | ||
to work independently on different parts of the GraphQL API, with the flexibility to use different | ||
technologies and programming languages. | ||
|
||
However, implementing Federation requires substantial infrastructure support, including a dedicated | ||
team to manage the gateway, schema registry, to help connect subgraphs to the federated API and guide | ||
teams on best practices. | ||
|
||
Before adopting Federation, it's crucial to consider whether your organization truly needs this | ||
level of complexity. | ||
|
||
Meta (formerly Facebook), [where GraphQL was created](/blog/2015-09-14-graphql/), has continued to | ||
use a monolithic GraphQL API since 2012. However, companies like | ||
[Netflix](https://netflixtechblog.com/how-netflix-scales-its-api-with-graphql-federation-part-1-ae3557c187e2), | ||
[Expedia Group](https://youtu.be/kpeVT7J6Bsw?si=srGWsoxf3kTmneTu&t=79), | ||
[Volvo](https://www.apollographql.com/blog/volvo-cars-drives-into-the-future-of-online-car-shopping-with-the-supergraph), | ||
and [Booking](https://youtu.be/2KsP_x50tGk?si=mu-MOG-xZQSDNDjh&t=478) have adopted Federation to | ||
better align with their organizational structures and microservices architecture. | ||
|
||
As you see, many industry leaders successfully federated their GraphQL APIs, proving that it works | ||
reliably for large-scale production applications. | ||
|
||
## Getting Started with GraphQL Federation | ||
|
||
If you're considering adopting GraphQL Federation, here are some steps to get started: | ||
|
||
1. **Identify Service Boundaries**: Define clear boundaries between different domains in your | ||
application | ||
2. [**Design Schemas**](/learn/schema/ 'Learn about the different elements of the GraphQL type system'): | ||
Create schemas that reflect these boundaries while considering how they'll interact | ||
3. [**Implement Subgraphs**](/community/tools-and-libraries/?tags=server 'Discover a list of GraphQL servers in our Tools and Libraries page'): | ||
Build individual services that implement their portion of the schema | ||
4. [**Set Up a Gateway**](/community/tools-and-libraries/?tags=gateways-supergraphs 'Discover a list of GraphQL gateways in our Tools and Libraries page'): | ||
Deploy a federation gateway to compose and serve the unified schema | ||
5. [**Use a Schema Registry**](/community/tools-and-libraries/?tags=schema-registry 'Discover a list of GraphQL schema registries in our Tools and Libraries page'): | ||
Manage schema composition and validation to ensure integrity across subgraphs | ||
|
||
When migrating from a monolithic GraphQL API to Federation, the simplest starting point is to treat | ||
your existing schema as your first subgraph. From there, you can follow the steps above to gradually | ||
decompose your schema into smaller pieces. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mjmahone I'd love to get your input on this paragraph.