This article walks through installing Apollo Federation, combining multiple GraphQL services, and running a federated GraphQL API locally.
1. Installing Apollo Federation for GraphQL
Apollo Federation extends GraphQL to support distributed architectures, allowing multiple services to contribute to a single graph. To set up Apollo Federation, follow these steps.
Step 1: Set Up a Node.js Project
Ensure you have Node.js (>=14.x) installed. Create a new directory and initialize a project:
mkdir graphql-federation
cd graphql-federation
npm init -y
Install the required dependencies:
npm install @apollo/federation @apollo/gateway graphql express
Step 2: Create a Simple GraphQL Service
Each microservice in a federated GraphQL setup is an independent GraphQL API.
users-service/index.js
:
const { ApolloServer, gql } = require('apollo-server');
const { buildSubgraphSchema } = require('@apollo/subgraph');
const typeDefs = gql`
type User @key(fields: "id") {
id: ID!
name: String!
}
type Query {
users: [User]
}
`;
const resolvers = {
User: {
__resolveReference(user) {
return users.find(u => u.id === user.id);
},
},
Query: {
users: () => users,
},
};
const users = [
{ id: '1', name: 'Alice' },
{ id: '2', name: 'Bob' },
];
const server = new ApolloServer({ schema: buildSubgraphSchema({ typeDefs, resolvers }) });
server.listen({ port: 4001 }).then(({ url }) => console.log(`Users service running at ${url}`));
Step 3: Create Another GraphQL Service
Let’s create another microservice to handle products.
products-service/index.js
:
const { ApolloServer, gql } = require('apollo-server');
const { buildSubgraphSchema } = require('@apollo/subgraph');
const typeDefs = gql`
type Product @key(fields: "id") {
id: ID!
title: String!
}
type Query {
products: [Product]
}
`;
const resolvers = {
Query: {
products: () => products,
},
};
const products = [
{ id: '101', title: 'Laptop' },
{ id: '102', title: 'Phone' },
];
const server = new ApolloServer({ schema: buildSubgraphSchema({ typeDefs, resolvers }) });
server.listen({ port: 4002 }).then(({ url }) => console.log(`Products service running at ${url}`));
2. Combine Multiple GraphQL Services
Now, let’s set up an Apollo Gateway that combines these services into a single federated GraphQL API.
Step 1: Create the Apollo Gateway
gateway/index.js
:
const { ApolloGateway } = require('@apollo/gateway');
const { ApolloServer } = require('apollo-server');
const gateway = new ApolloGateway({
serviceList: [
{ name: 'users', url: 'http://localhost:4001' },
{ name: 'products', url: 'http://localhost:4002' },
],
});
const server = new ApolloServer({ gateway, subscriptions: false });
server.listen({ port: 4000 }).then(({ url }) => console.log(`Gateway running at ${url}`));
Step 2: Test the Federated GraphQL API
Start all services:
node users-service/index.js &
node products-service/index.js &
node gateway/index.js
Now, query the unified API:
query {
users {
id
name
}
products {
id
title
}
}
This will return data from both microservices via the Apollo Gateway.
3. Running a Federated GraphQL API Locally
To run everything efficiently:
- Ensure each service is running on separate ports.
- Start the gateway, which aggregates the services.
- Use GraphQL Playground (Apollo Server default UI) to test queries.
Step 1: Running Services in Parallel
Use a process manager like PM2 to run services efficiently:
npm install -g pm2
pm2 start users-service/index.js --name users
pm2 start products-service/index.js --name products
pm2 start gateway/index.js --name gateway
Step 2: Validate Federation
To confirm federation works correctly:
- Check logs:
pm2 logs
- Query the gateway:
http://localhost:4000
Conclusion
GraphQL Federation simplifies microservices communication while keeping services independent. With Apollo Federation, you can efficiently compose multiple GraphQL APIs into a single schema, improving scalability and maintainability.
Key takeaways:
- Apollo Federation enables distributed GraphQL architecture.
- Subgraphs (microservices) define their own schema and reference each other.
- Apollo Gateway unifies multiple GraphQL services into a single API.
- Running services locally with a process manager ensures stability.
By implementing these techniques, you can build a scalable GraphQL microservices architecture with seamless inter-service communication.