An introduction to GraphQL federation

Microservices, the latest iteration of service-oriented architecture (SOA), are the biggest trend in the software development industry, and GraphQL is becoming the preferred query language due to its flexibility. But microservices can be difficult to work with. For example, how do you avoid multiple endpoints for users? One solution is to implement federation.

What Is GraphQL federation?

Federated architecture brings different services together into one API endpoint. As an example, imagine you have an application that gives you an overview of Apollo missions and their crew members.

In a typical monolith scenario, you would have a single application that would give you all the needed information about the different missions and crew members. Instead, what you would want is one service to manage information about missions and another service to manage information about astronauts. In this case, you could easily split your monolith into two GraphQL instances. However, now, your frontend would no longer work because it would need to call two different APIs then stitch the information together.

GraphQL federation allows you to set up a single GraphQL API, or a gateway, that fetches from all your other APIs. Your mission service and your astronaut service are now *subgraphs*.

Your frontend only needs to query the gateway no matter how the services are split up behind it. You can also progressively split up your monolith without changing the frontend. So you can keep the logic for missions in the monolith, for instance, and split out the logic for astronauts. Your frontend queries the gateway, and the gateway queries either the monolith or the astronaut service, depending on what’s needed.

Federation vs schema stitching

Schema stitching was the previous solution for microservice architecture. Both federation and schema stitching do offer the same functionality on the surface, gathering multiple services into one unified gateway, but the implementation is different.

With GraphQL federation, you tell the gateway where it needs to look for the different objects and what URLs they live at. The subgraphs provide metadata that the gateway uses to automatically stitch everything together. This is a low-maintenance approach that gives your team a lot of flexibility.

With schema stitching, you must define the “stitching” in the gateway yourself. Your team now has a separate service that needs to be altered, which limits flexibility. The use case for schema stitching is when your underlying services are not all GraphQL. Schema stitching allows you to create a gateway connected to a REST API, for example, while federation only works with GraphQL.

So when should you use either one? Many will say that federation is the overall winner, as it allows teams to focus on their application without needing to maintain a gateway. But if you have different types of APIs, you have to go with schema stitching.

Apollo federation implementation

Following is a general guide on how to implement federation. For step-by-step instructions, I recommend watching the video example linked earlier.

Creating a gateway

To start, you need to create the gateway. You can use a boilerplate template project, or you can manually install the required packages by running `npm install apollo-server @apollo/gateway graphql`. Once they’re installed, create the gateway with a single file `index.js`.

const { ApolloServer } = require('apollo-server');
const { ApolloGateway } = require('@apollo/gateway');

const supergraphSdl = ''; // TODO!

const gateway = new ApolloGateway({
  supergraphSdl
});

const server = new ApolloServer({
  gateway
});

server.listen().then(({ url }) => {
  console.log(`Gateway ready at ${url}`);
}).catch(err => {console.error(err)});

Your gateway is ready, but it doesn’t have subgraphs connected. To do that, you need to create what’s known as the *supergraph*.

Creating the supergraph schema

As with the gateway, there are different ways to create the supergraph. One recommended method is to use the Rover CLI, which needs a YAML file that details where the subgraphs live. Here’s an example:

subgraphs:
  astronauts:
    routing_url: https://localhost:4001
    schema:
      subgraph_url: https://localhost:4001
  missions:
    routing_url: https://localhost:4002
    schema:
      subgraph_url: https://localhost:4002

Name the above file `supergraph-config.yaml`. Run the following command to generate the supergraph schema and output it to `supergraph.graphql`:

$ rover supergraph compose --config ./supergraph-config.yaml > supergraph.graphql

Starting the gateway

Now add the supergraph schema to the `index.js` file. Replace the contents of the file with the code below to pull in the contents of the `supergraph.graphql` file you created:

const { ApolloServer } = require('apollo-server');
const { ApolloGateway } = require('@apollo/gateway');
const { readFileSync } = require('fs');

const supergraphSdl = readFileSync('./supergraph.graphql').toString();

const gateway = new ApolloGateway({
  supergraphSdl
});

const server = new ApolloServer({
  gateway
});

server.listen().then(({ url }) => {
  console.log(`Gateway ready at ${url}`);
}).catch(err => {console.error(err)});

As you can see, it’s not too complicated to get started with GraphQL federation.

Challenges with using GraphQL federation

The greatest difficulty in using federation is figuring out _when_ to use it. Many teams find it improves their infrastructure and increases performance. But that isn’t true in all cases.

For instance, does your frontend use many different endpoints to make a single piece of the application function? If so, then federation may be a good choice for you. If you only use one or two endpoints, then the extra complexity added by having to manage a gateway may not be worth it.

Federation requires extra infrastructure, and every new piece added brings more complexity. Also, you will need to work with your services a bit differently. Adding federation may be simple, but adding it effectively takes more work and time. You need to understand the new paradigm it offers and be sure your specific infrastructure can take advantage of it.

Tips for using federation

One of the things you can do to improve your federation experience is building your schema as you go. Federation allows you to break pieces up and use an agile approach to better integrate it so that it keeps running smoothly.

The best way to do that is to divide your services by _concern_. Take a look at your monolith or your existing microservices and determine their specific purpose. In the example above, missions and astronauts each have their own concerns.

Conclusion

GraphQL federation offers a lot of benefits to developers. It allows you to combine the simplicity of GraphQL with the flexibility of microservices.

As you use federation, you may find you’re creating many more APIs. Tyk is a cloud-native API platform that works with GraphQL, provides scalable API management for microservice architecture. Tyk may just be the right solution for your business.