What is @apollo/federation?
@apollo/federation is a library that enables the composition of multiple GraphQL services into a single unified graph. It allows you to build a federated data graph, which can be composed of multiple subgraphs, each managed by different teams or services.
What are @apollo/federation's main functionalities?
Defining a Federated Schema
This code demonstrates how to define a federated schema using @apollo/federation. It includes type definitions and resolvers for a Product type, and sets up an Apollo Server with the federated schema.
const { buildFederatedSchema } = require('@apollo/federation');
const { ApolloServer, gql } = require('apollo-server');
const typeDefs = gql`
type Product @key(fields: "id") {
id: ID!
name: String
}
extend type Query {
product(id: ID!): Product
}
`;
const resolvers = {
Product: {
__resolveReference(product) {
return { id: product.id, name: "Sample Product" };
}
},
Query: {
product(_, { id }) {
return { id, name: "Sample Product" };
}
}
};
const server = new ApolloServer({
schema: buildFederatedSchema([{ typeDefs, resolvers }])
});
server.listen({ port: 4000 }).then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
Extending Types Across Services
This code demonstrates how to extend types across different services using @apollo/federation. It shows how to add a reviews field to the Product type, which is defined in another service.
const { buildFederatedSchema } = require('@apollo/federation');
const { ApolloServer, gql } = require('apollo-server');
const typeDefs = gql`
extend type Product @key(fields: "id") {
id: ID! @external
reviews: [Review]
}
type Review {
id: ID!
content: String
}
extend type Query {
reviews(productId: ID!): [Review]
}
`;
const resolvers = {
Product: {
reviews(product) {
return [{ id: "1", content: "Great product!" }];
}
},
Query: {
reviews(_, { productId }) {
return [{ id: "1", content: "Great product!" }];
}
}
};
const server = new ApolloServer({
schema: buildFederatedSchema([{ typeDefs, resolvers }])
});
server.listen({ port: 4001 }).then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
Gateway Setup
This code demonstrates how to set up an Apollo Gateway to compose multiple federated services into a single graph. It includes a service list with URLs for the products and reviews services.
const { ApolloServer } = require('apollo-server');
const { ApolloGateway } = require('@apollo/gateway');
const gateway = new ApolloGateway({
serviceList: [
{ name: 'products', url: 'http://localhost:4000' },
{ name: 'reviews', url: 'http://localhost:4001' }
]
});
const server = new ApolloServer({
gateway,
subscriptions: false
});
server.listen({ port: 4002 }).then(({ url }) => {
console.log(`🚀 Gateway ready at ${url}`);
});
Other packages similar to @apollo/federation
graphql-tools
graphql-tools is a set of utilities from Apollo that can be used to create and manipulate GraphQL schemas. While it does not provide the same level of federation capabilities as @apollo/federation, it is useful for schema stitching and other schema-related tasks.
graphql-mesh
graphql-mesh allows you to use GraphQL to query any service, whether it is a REST API, SOAP, gRPC, or another GraphQL API. It provides a way to unify different data sources into a single GraphQL schema, similar to @apollo/federation, but with a broader range of data source support.
Apollo Federation Utilities
This package provides utilities for creating GraphQL microservices, which can be combined into a single endpoint through tools like Apollo Gateway.
For complete documentation, see the Apollo Federation API reference.
Usage
const { ApolloServer, gql } = require("apollo-server");
const { buildSubgraphSchema } = require("@apollo/federation");
const typeDefs = gql`
type Query {
me: User
}
type User @key(fields: "id") {
id: ID!
username: String
}
`;
const resolvers = {
Query: {
me() {
return { id: "1", username: "@ava" }
}
},
User: {
__resolveReference(user, { fetchUserById }){
return fetchUserById(user.id)
}
}
};
const server = new ApolloServer({
schema: buildSubgraphSchema([{ typeDefs, resolvers }])
});