Combining GraphQL Schemas for Federated Subgraphs | by Miles Bardon | Mar, 2022

Convert a number of schema recordsdata into one

Picture by JESHOOTS.COM on Unsplash

TL;DR — @graphql-tools/utils exports the printSchemaWithDirectives operate to transform your GraphQLSchema object again to a schema string.

An attention-grabbing conundrum offered itself while planning emigrate a monolith GraphQL server to Apollo Federation. Our schema is cut up up into a number of recordsdata to ease the ache of getting half a dozen groups work on the identical schema, and we use the # import syntax to hitch all of them collectively.

On this brief weblog, I’ll clarify how we’re capable of merge these a number of recordsdata into one, which might then be used to create a beginning subgraph for a federated gateway.

For the needs of this text, I’ve created 4 recordsdata that may signify our schema distributed over a number of .graphql recordsdata.

// schema.graphl# import Put up from "posts.graphql"sort Question 
posts: [Post]
// posts.graphql# import Remark from 'feedback.graphql'"""
A put up with feedback
"""
sort Put up
feedback: [Comment]
id: ID!
textual content: String!
tags: [String]
// feedback.graphql# import uppercase from './directives.graphql'sort Remark
id: ID!
textual content: String! @uppercase
// directives.graphqldirective @uppercase on FIELD_DEFINITION

These recordsdata exhibit a wide range of frequent schema syntax, together with nested varieties (i.e. Remark), feedback (i.e. on Put up ) and directives (i.e. @uppercase )

graphql-tools offers us the capabilities we have to load in all these schema recordsdata right into a single GraphQLSchema object that we are able to then print out. In the event you’re following alongside, create a brand new Node package deal in the identical listing that you simply wrote the schema recordsdata;

$ npm init -y
$ npm i -D graphql @graphql-tools/graphql-file-loader @graphql-tools/load

The schema recordsdata might be loaded right into a single object with this brief script

const  loadSchemaSync  = require("@graphql-tools/load");
const GraphQLFileLoader = require("@graphql-tools/graphql-file-loader");
const schema = loadSchemaSync("./schema.graphql",
loaders: [new GraphQLFileLoader()],
);

The # import key phrase tells the loadSchemaSync operate the place to search out the required varieties, and so long as there aren’t any syntax errors in your schema recordsdata, this operate will execute with none errors.

graphql-tools/utils exposes one other useful operate, printSchemaWithDirectives, constructed on high of the printSchema operate from the graphql.js package deal. Utilizing this, we are able to add to our earlier script to lastly write the printed schema to a mixed.graphql schema.

const fs = require("fs");const  loadSchemaSync  = require("@graphql-tools/load");
const GraphQLFileLoader = require("@graphql-tools/graphql-file-loader");
const printSchemaWithDirectives = require("@graphql-tools/utils");
const schema = loadSchemaSync("./schemas/schema.graphql",
loaders: [new GraphQLFileLoader()],
);
fs.writeFileSync("mixed.graphql", printSchemaWithDirectives(schema));

The ensuing file appears like this;

// mixed.graphqlschema 
question: Question
directive @uppercase on FIELD_DEFINITIONsort Question
posts: [Post]
"""A put up with feedback"""
sort Put up
feedback: [Comment]
id: ID!
textual content: String!
tags: [String]
sort Remark
id: ID!
textual content: String! @uppercase

We’ve transformed our a number of schema recordsdata into one, and may now run it by the rover CLI device to generate our supergraph schema.

For some, like us, this can be step one to federating a monolith graph and, hopefully, this potential to recreate a schema file from a GraphQLSchema object is beneficial to you on this endeavor.

More Posts