Catch the highlights of GraphQLConf 2023!Click for recordings.Or check out our recap blog post.
v5 (latest)
Features
Apollo Federation

Apollo Federation

Apollo Federation (opens in a new tab) is a specification that applies microservice architecture through GraphQL APIs.

Thanks to Envelop's Apollo Federation (opens in a new tab) plugin, we can use GraphQL Yoga to build our gateway server.

💡

As documented in the Apollo Federation docs (opens in a new tab), @apollo/gateway package doesn't support GraphQL v16 so you have to install graphql@15.

💡

Please note that Apollo Federation implementation doesn't support GraphQL Subscriptions. If you need to use Subscriptions with a Federated Gateway you can use Schema Stitching (opens in a new tab).

Gateway

Installation for Gateway

npm i @apollo/gateway @envelop/apollo-federation graphql-yoga graphql@15

Example Gateway

import { createServer } from 'http'
import { createYoga } from 'graphql-yoga'
import { ApolloGateway } from '@apollo/gateway'
import { useApolloFederation } from '@envelop/apollo-federation'
 
// Initialize the gateway
const gateway = new ApolloGateway({
  serviceList: [
    { name: 'accounts', url: 'http://localhost:4001' },
    { name: 'products', url: 'http://localhost:4002' }
    // ...additional subgraphs...
  ]
})
 
// Make sure all services are loaded
await gateway.load()
 
const yoga = createYoga({
  plugins: [
    useApolloFederation({
      gateway
    })
  ]
})
 
// Start the server and explore http://localhost:4000/graphql
const server = createServer(yoga)
server.listen(4000, () => {
  console.info('Server is running on http://localhost:4000/graphql')
})

Handling Subgraph Errors

By default, GraphQL Yoga masks any unexpected GraphQL Errors. This is done to prevent leaking internal errors to the client. If you know that your subgraph is safe and you want to expose the errors to the client, you can customize the error masking bahviour.

Learn more about error masking

Expose subgraph errors to the client
import { createYoga, maskError } from 'graphql-yoga'
import { schema } from './schema.js'
 
const yoga = createYoga({
  schema,
  maskedErrors: {
    maskError(error, message, isDev) {
      if (error?.extensions?.code === 'DOWNSTREAM_SERVICE_ERROR') {
        return error
      }
 
      return maskError(error, message, isDev)
    }
  }
})

Federation Service

You don't need any extra plugins for Yoga for Federation Service.

Installation

npm i graphql-yoga @apollo/subgraph graphql

Example User Service

const { parse } = require('graphql')
const { buildSubgraphSchema } = require('@apollo/subgraph')
const { createYoga } = require('graphql-yoga')
const { createServer } = require('http')
 
const typeDefs = parse(/* GraphQL */ `
  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 yoga = createYoga({
  schema: buildSubgraphSchema([{ typeDefs, resolvers }])
})
 
const server = createServer(yoga)
 
server.listen(4001, () => {
  console.log(`🚀 Server ready at http://localhost:4001`)
})

Federated tracing

Inject additional metrics for Apollo's federated tracing (opens in a new tab).

You'll need the @graphql-yoga/plugin-apollo-inline-trace Yoga plugin for this.

Installation

npm i graphql-yoga @graphql-yoga/plugin-apollo-inline-trace graphql

Example Federated tracing

import { createServer } from 'http'
import { createYoga } from 'graphql-yoga'
import { useApolloInlineTrace } from '@graphql-yoga/plugin-apollo-inline-trace'
 
const yoga = createYoga({
  plugins: [
    useApolloInlineTrace()
    // ...rest of your Apollo federation plugins
  ]
})
 
// Start the server and explore http://localhost:4000/graphql
const server = createServer(yoga)
server.listen(4000, () => {
  console.info('Server is running on http://localhost:4000/graphql')
})

Working Example

Check our working example (opens in a new tab) to try it out.