Unifying GraphQL Schemas: A Deep Dive into Schema Stitching

In the world of GraphQL, schema stitching is a powerful technique that allows developers to combine multiple schemas into a single, unified schema. This approach is particularly useful in large-scale applications where multiple services need to be integrated, and each service has its own schema.

Why Schema Stitching?

In a typical GraphQL setup, each service would have its own schema, and clients would need to query multiple APIs to retrieve the required data. However, with schema stitching, clients can query a single, unified schema that combines the fields and resolvers from multiple services. This approach simplifies the development process, reduces complexity, and improves performance.

How Schema Stitching Works

Schema stitching involves creating a gateway that acts as an intermediary between the client and the individual services. The gateway receives queries from the client, delegates them to the relevant services, and then combines the responses into a single result.

To achieve this, the gateway needs to know which service is responsible for resolving each field in the query. This information is stored in the stitched schema configuration, which maps each field to the corresponding service.

Practical Example: Stitching Schemas from Different Modules

Let’s consider an example where we have two services: reviews and books. Each service has its own schema, and we want to create a unified schema that combines the fields from both services.

We start by defining the schemas for each service:
“`graphql
// reviews.graphql
type Review {
id: ID!
title: String!
content: String!
}

// books.graphql
type Book {
id: ID!
title: String!
author: String!
}

Next, we create a gateway that stitches the two schemas together:
javascript
const { stitchSchemas } = require(‘graphql-stitch’);
const reviewsSchema = require(‘./reviews.graphql’);
const booksSchema = require(‘./books.graphql’);

const gatewaySchema = stitchSchemas({
subschemas: [reviewsSchema, booksSchema],
});
“`
The resulting gateway schema will contain all the fields from both services, and clients can query it as if it were a single, unified schema.

Stitching Remote Schemas

In addition to stitching schemas from different modules, we can also stitch remote schemas that are running on separate servers. This is achieved using a technique called introspection, which allows us to query the remote schema for information about its fields and resolvers.

For example, let’s say we have a remote schema running on a server at http://example.com/graphql. We can use introspection to fetch the schema and stitch it into our gateway:
“`javascript
const { introspectSchema } = require(‘graphql-stitch’);
const remoteSchemaUrl = ‘http://example.com/graphql’;

const remoteSchema = await introspectSchema(remoteSchemaUrl);
const gatewaySchema = stitchSchemas({
subschemas: [reviewsSchema, booksSchema, remoteSchema],
});
“`
Type Merging

When stitching schemas, it’s common for types to be defined in multiple services. In such cases, we need to merge the types to ensure that the gateway can resolve fields correctly.

For example, let’s say we have a Book type defined in both the reviews and books services. We can merge the types by adding a merge configuration to the gateway:
javascript
const gatewaySchema = stitchSchemas({
subschemas: [reviewsSchema, booksSchema],
merges: [
{
typeName: 'Book',
fieldName: 'reviews',
selectionSet: '{ id title }',
args: (parent, args) => ({ id: parent.id }),
},
],
});

This configuration tells the gateway to merge the Book type from both services, and to resolve the reviews field by querying the reviews service with the id argument.

Conclusion

Schema stitching is a powerful technique for unifying multiple GraphQL schemas into a single, cohesive schema. By using a gateway to stitch together schemas from different modules or remote servers, we can simplify our development process, reduce complexity, and improve performance. With the help of type merging, we can ensure that our gateway can resolve fields correctly, even when types are defined in multiple services.

Leave a Reply

Your email address will not be published. Required fields are marked *