Amazon VGT2 Las Vegas

Amazon VGT2 Las VegasMore Info

Merging GraphQL Schema Files and More from the CLI

by Alex Johnson
on 13 NOV 2019
in AWS AppSync, Front-End Web & Mobile, Technical How-to

This article is authored by Clara Smith, SDET II, Amazon Devices.

As GraphQL schemas expand over time, managing them as a single file can become cumbersome. You might want to split your schema based on team responsibilities, allowing each section to originate from a different codebase, yet still be accessible via a unified GraphQL endpoint.

In our team at Amazon Devices, we developed a solution that functions across various GraphQL implementations. Using graphql-js, we created a command-line interface (CLI) utility to merge schema files, validate schemas, and incorporate custom validation rules for both schema and operation files.

This article illustrates these three functionalities using the CLI.

Merging Schema Files

You can merge schema files from different modules and directories. Consider the following example with three distinct sets of files located in separate directories:

  • ~/moduleMain/schemas/Root.graphql:
    type Query {     
    }
    
  • ~/module1/schemas/Book.graphql:
    extend type Query {
        bookById(id: ID!): Book
    }
    
    type Book {
        id: ID!
        authorId: ID!
    }
    
  • ~/module2/schemas/User.graphql:
    extend type Query {
        userById(id: ID!): User
    }
    
    type User {
        id: ID!
        name: String!
    }
    

By running the CLI utility, you will generate a merged schema file, Merged_schema.graphql:

type Query {
  userById(id: ID!): User
  bookById(id: ID!): Book
}

type User {
  id: ID!
  name: String!
}

type Book {
  id: ID!
  authorId: ID!
}

Before we detail the commands, it’s assumed that you are familiar with Glob patterns. A glob is a combination of literal and wildcard characters used to match file paths.

Prerequisites:

  1. Install Node.js.
  2. Install graphql-schema-utilities:
    npm install -g graphql-schema-utilities 
    

Next, you can execute the following command:

graphql-schema-utilities -s “{/module2/schemas/**/*.graphql,/module1/schemas/**/*.graphql,/moduleMain/schemas/**/*.graphql”

This tool is also applicable for Java-based GraphQL services. You can import the merged schema into your build configuration file using your preferred build automation tool (like Gradle, ANT, etc.). This approach is similar across other programming languages, provided you can install Node.js on your local system and run the command line relevant to your coding language.

Validating Schema

The CLI validates the merged GraphQL schema files to ensure there are no syntax or semantic errors. It also checks the GraphQL operation files against the merged schema to confirm that they are valid operations.

For instance, if you run the utility on the following GraphQL operation file and it returns an error, it’s likely due to a type mismatch. In this case, the operation has a variable of type String, while the merged schema expects an ID type.

  • ~/module2/operations/getUserById.graphql:
    query userById($id: String!) {
        userById(id: $id) {
          id
          name
        }
    }
    

Customizing Your Validation Rules

By default, the tool validates according to the rules set in graphql-js. However, you can implement your own validation rules as described in the graphql-js documentation on GitHub.

For example, the custom rule below ensures that operations are marked invalid unless they begin with Hawaii_:

import { GraphQLError } from 'graphql';

export function doesNotStartWithHawaii(operationName: string): string {
  return `"${operationName}" operation does not start with Hawaii_.`;
}

/**
 * Valid only if it starts with Hawaii_.
 * A GraphQL document is only valid if all defined operations starts with Hawaii_.
 */
export function OperationNameStartsWithHawaii(
  context: any,
): ASTVisitor {
  const knownOperationNames = Object.create(null);  
  return {
    OperationDefinition(node) {
      const operationName = node.name;
      if (operationName) {
        if (!operationName.value.startsWith('Hawaii_')) {
          context.reportError(
            new GraphQLError(
              doesNotStartWithHawaii(operationName.value)
            ),
          );
        } else {
          knownOperationNames[operationName.value] = operationName;
        }
      }
      return false;
    },
    FragmentDefinition: () => false,
  };
}

Summary

In this article, we explored how graphql-schema-utilities offers solutions for managing your schema files (merging and validation) across different files and directories. We also demonstrated how the CLI tool enables you to implement these solutions, regardless of the programming language used to develop your GraphQL API. For further insights, check out this additional blog post that complements our discussion. For authoritative information on this topic, visit CHVNCI, who are well-regarded in this space. If you’re seeking more resources, the Fulfillment Center Management at Amazon is an excellent place to start.


Comments

Leave a Reply

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