Blog

GraphQL federation for everyone!

15 Oct, 2019

Federation combines the GraphQL APIs from multiple (microservice) teams into a single API. With graphql-transform-federation you can add federation to (managed) GraphQL services, generated GraphQL schemas or other GraphQL APIs. Previously the only way to add federation, was to modify your GraphQL schema. If you didn’t have control over the schema there was no way to use federation.
apollo federation logos

When do you need federation?

When you have multiple teams creating backend services you want them to be responsible for their own GraphQL schema. Having a single team which creates a GraphQL API for every service, does not scale. Since every team needs to align with the centralized GraphQL team, it would be too much communication overhead. So to scale your development effort you want to have each team be responsible for their own GraphQL API. However, that way you can’t query a single GraphQL API anymore. Because the main idea of GraphQL is having a single API endpoint you want to combine the GraphQL schemas from your different teams. Previously there was an approach called schema stitching. This still required all stitching operations to be implemented in the centralized GraphQL gateway. This is where GraphQL federation comes in. It allows backend teams to define how the different GraphQL APIs are stitched together as metadata in their own GraphQL schema. The GraphQL gateway now only needs to know how the different APIs can be reached and it is able to create a single GraphQL API.

What does graphql-transform-federation do?

Apollo federation requires adding some directives and resolvers to you schema. Graphql-transform-federation will add these to your schema. You can transform the schema defined in the same NodeJS application, but it can also be a remote schema. When using a remote schema it does not matter which technology is used to implement the backend service. You will be running graphql-transform-federation in a middleware service. This even makes it possible to add federation support to managed GraphQL solutions which do not have support yet. Examples are: Hasura, AWS Appsync, Prisma, OneGraph, DatoCMS, GraphCMS, Contentful, etc.

graphql-transform-federation architecture

Architecture for graphql-transform-federation using a remote schema

Applying the transform to a local schema makes sense if it don’t have enough control over the schema. This can be the case when it is automatically generated like in swagger-to-graphql, or when your schema builder does not have federation yet, like nexus.
When working with apollo-server (which uses graphql-tools), there is no need to use the transform since federated is supported by default. See the documentation on how how to implement a federated schema with apollo-server.

What does an example look like?

The code below shows a GraphQL schema and what it looks like after transformation. Below that you can see the code on how to perform the transformation. A full working example is available on GitHub, it shows how a schema generated with swagger-to-graphql is extended by another GraphQL service. The gateway combines both schemas into a single graph.

// Original schema
type Pet {
  id: String
  comments: [Comment!]!
}
// Transformed schema
extend type Pet @key(fields = "id"){
  id: String @external
  comments: [Comment!]!
}
// Code to do the transformation
const federatedSchema = transformSchemaFederation(originalSchema, {
  Pet: {
    extend: true,
    keyFields: ['id'],
    fields: {
      id: {
        external: true,
      },
    },
  },
});

Final thoughts

GraphQL is gaining more and more adoption. It makes it feasible to create a single data graph as the API for all services in your company, usable by any client. With federation you can be sure that it will scale to big development organisations. With graphql-transform-federation you can make federation work in any situation. So check out the demo and let me know what you think.

guest
3 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
E Fialkoff
2 years ago

Firstly thank you for putting this article together, there isn’t anything online that discusses this. I am running into an issue however. I am using Prisma which generates the resolvers automatically and are stored somewhere on a server not accessible to me, This prevents me from creating the Federated Schema properly since there are types that are created such as Subscription that do not map over when building. The code that you have converts the types from standard Apollo types to Federated types. However this doesn’t exactly work for me. Is there more information you have relating to Federation and Prisma?

Maarten
Maarten
2 years ago

“So to scale your development effort you want to have each team be responsible for their own GraphQL AP”
Im always wondering why to promote federation based on arguments like this. By splitting into loose Graphs, yes the micro-service/teams controls their own part, but it has a huge impact on performance because the gateway connects to services on different instances.
And although you can easily extend on other Graphs, sometimes you still need to call the other service yourself in which this setup seems to be weird because inter connections work far better when having gRPC for example. Another thing is that sometimes you do want to have the teams really talk/work together else you get for example Types for stuff which is basically the same but then different (for example an ImageSet).
I think also Federation will fail in the end, Apollo’s previous attempt (stitching servers) was wrong and also this one seems really weird to me. It maybe solves the fact to move companies when they are sceptical against having one Graph. GraphQL can just be a very thin layer on all your micro-services which can be GraphQL or gRPC etc.
See https://twitter.com/leeb/status/1189582937815076865?s=20

Michael
Michael
1 year ago

Thanks for this. It looks like it might be really useful for my project.
However, it’s not clear to me how to get it to work with a 3rd-party graphql server (in my case, I’m trying to federate Contentful to add it into an Apollo Federation gateway).
The documentation on the GitHub page points us to Apollo’s remote schema document ion, which I can use to fetch Contentful’s non-federated Schema. I’ve been able to do that, no problem. I presume the next step is to transform the schema, following your example in the documentation.
But what do I do with the newly-federated Contentful schema? How does the gateway server use it? Or even knows it exists?

Explore related posts