Fetching latest headlines…
Split your AWS AppSync schema across multiple files
NORTH AMERICA
πŸ‡ΊπŸ‡Έ United Statesβ€’April 18, 2026

Split your AWS AppSync schema across multiple files

1 views0 likes0 comments
Originally published byDev.to

If you’re working with AWS AppSync or any modular GraphQL API, you’ve probably want to split your schema across multiple files. This is great for developer sanityβ€”but AppSync prefers a single .graphql file.

Let’s automate that.

This post walks through a simple Node.js script that uses the @graphql-tools ecosystem to:

βœ… Load and merge your GraphQL schemas
βœ… Resolve conflicts
βœ… Write the final result to a single .graphql file
βœ… load schema into your AppSync deployment flow

πŸ›  Setup

Install the necessary dependencies:

npm install @graphql-tools/load-files @graphql-tools/merge graphql

πŸ“¦ Your Project Structure

Assume your project is organized like this:

project-root/
β”œβ”€β”€ appsync/
β”‚   β”œβ”€β”€ mutations/
β”‚   β”‚   └── addCustomer.graphql
β”‚   β”œβ”€β”€ queries/
β”‚   β”‚   └── getCustomer.graphql
β”‚   └── schema_chatbot_quicksight_merged.graphql (output)
β”œβ”€β”€ mergeSchemas.js

🧩 The Merge Script

Here’s the full script to merge your GraphQL schema files:

import { loadFilesSync } from "@graphql-tools/load-files";
import { mergeTypeDefs } from "@graphql-tools/merge";
import { print } from "graphql";
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";

try {
    const __filename = fileURLToPath(import.meta.url);
    const __dirname = path.dirname(__filename);
    const mergedFileName = "schema_chatbot_quicksight_merged.graphql";
    const outputPath = path.join(__dirname, "./appsync", mergedFileName);

    const typesArray = loadFilesSync(path.join(__dirname, "./appsync/**/*.graphql"), {
        extensions: [".graphql"],
        ignore: [mergedFileName],
    });

    if (!typesArray || typesArray.length === 0) {
        throw new Error("No GraphQL schema files found");
    }

    console.log(
        "Loaded files:",
        typesArray.map((t) => t?.loc?.source?.name || typeof t),
    );

    const mergedTypeDefs = mergeTypeDefs(typesArray, {
        all: true,
        throwOnConflict: true,
    });

    const sdl = print(mergedTypeDefs);

    const outputDir = path.dirname(outputPath);
    if (!fs.existsSync(outputDir)) {
        fs.mkdirSync(outputDir, { recursive: true });
    }

    fs.writeFileSync(outputPath, sdl);
    console.log(`βœ… Merged schema written to appsync/${mergedFileName}`);
} catch (error) {
    console.error("❌ Error merging GraphQL schemas:", error.message);
    process.exit(1);
}

πŸš€ Using It in AWS CDK

Once your merged schema is generated, you can use it directly in your CDK stack with aws-cdk-lib/aws-appsync.

Here’s an example:

import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import * as appsync from "aws-cdk-lib/aws-appsync";
import * as path from "path";

export class AppsyncStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const api = new appsync.GraphqlApi(this, "graphql-api", {
      name: "ChatbotQuickSightApi",
      schema: appsync.SchemaFile.fromAsset(
        path.join(__dirname, "../appsync/schema_chatbot_quicksight_merged.graphql")
      ),
      authorizationConfig: {
        defaultAuthorization: {
          authorizationType: appsync.AuthorizationType.API_KEY,
        },
      },
      xrayEnabled: true,
    });

    new cdk.CfnOutput(this, "GraphQLAPIURL", {
      value: api.graphqlUrl,
    });
  }
}

🧠 Tip

You can run your mergeSchemas.js script as part of your CDK build pipeline. For example:

"scripts": {
  "prepare-schema": "node mergeSchemas.js",
  "build": "npm run prepare-schema && cdk synth"
}

🧼 Why This Matters

  • Keep your schema modular for readability and reuse
  • Deliver a single file AppSync expects without error-prone copy/paste
  • Enable CI/CD integration with schema validation and bundling in one step

Comments (0)

Sign in to join the discussion

Be the first to comment!