The Guild LogoThe Guild Monogram
GraphQL Tools

GraphQL Tools

A set of utilities for faster GraphQL development

Get Started

Loading GraphQL Schemas from different sources#

These utils are useful for scanning, loading and building a GraphQL schema from any input.

You can specify a GraphQL endpoint, local introspection JSON file, code file that exports a GraphQLSchema, AST string and .graphql files (with support for glob expression).

All found schema files can be merged into a complete schema. There is support for #import syntax (formerly known as graphql-import).

The user is given the option of implementing their own loader (implement the interface SchemaLoader).

The schema loading util is using loaders, and implemented using chain-of-responsibility pattern.

Specifying the loader is not necessary. The user need only provide the inputs. The utils will detect it automatically.

For notes on typescript, refer to loaders

Schema and documents loading doesn't work non Node.js environments, and if you are using a bundler like webpack, rollup or vite, you cannot use dynamic loaders.

Load typeDefs/DocumentNode and resolvers from files#

const { loadFiles } = require('@graphql-tools/load-files') const { createServer } = require('@graphql-yoga/node') async function main() { const server = createServer({ server: { typeDefs: await loadFiles('src/typeDefs/**/*.graphql'), resolvers: await loadFiles('src/resolvers/**/*.{js,ts}') } }) await server.start() }

loadFiles doesn't support #import syntax. See below if you need that.

Load GraphQLSchema by using different loaders from different sources#

const { loadSchema } = require('@graphql-tools/load') const { UrlLoader } = require('@graphql-tools/url-loader') const { JsonFileLoader } = require('@graphql-tools/json-file-loader') const { GraphQLFileLoader } = require('@graphql-tools/graphql-file-loader') async function main() { // load from string w/ no loaders const schema1 = await loadSchema('type A { foo: String }') // load from endpoint const schema2 = await loadSchema('http://localhost:3000/graphql', { loaders: [new UrlLoader()] }) // load from local json file const schema3 = await loadSchema('./schema.json', { loaders: [new JsonFileLoader()] }) // load from a single schema file const schema4 = await loadSchema('schema.graphql', { loaders: [new GraphQLFileLoader()] }) // load from multiple files using glob const schema5 = await loadSchema('./src/**/*.graphql', { loaders: [new GraphQLFileLoader()] }) } main()

Using #import expression#

Assume the following directory structure:

. ├── schema.graphql ├── posts.graphql └── comments.graphql

schema.graphql

# import Post from "posts.graphql" type Query { posts: [Post] }

posts.graphql

# import Comment from 'comments.graphql' type Post { comments: [Comment] id: ID! text: String! tags: [String] }

comments.graphql

type Comment { id: ID! text: String! }

Running loadSchema produces the following output:

type Query { posts: [Post] } type Post { comments: [Comment] id: ID! text: String! tags: [String] } type Comment { id: ID! text: String! }

Binding to HTTP Server#

You can extend loaded schema with resolvers

import { join } from 'path' import { loadSchemaSync } from '@graphql-tools/load' import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader' import { addResolversToSchema } from '@graphql-tools/schema' import { createServer } from '@graphql-yoga/node' async function main() { // Load schema from the file const schema = await loadSchema(join(__dirname, './schema.graphql'), { loaders: [new GraphQLFileLoader()] }) // Write some resolvers const resolvers = {} // Add resolvers to the schema const schemaWithResolvers = addResolversToSchema({ schema, resolvers }) const server = createServer({ schema: schemaWithResolvers }) await server.start() } main().catch(error => console.error(error))

Loaders#

There are a lot of loaders that load your schemas and documents from different sources. You need to provide those loaders under loaders parameter like below;

Watch Episode #22 of graphql.wtf for a quick introduction to file loaders:

GraphQL File Loader#

This loader loads your GraphQLSchema from .graphql files like below;

import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader'; import { addResolversToSchema } from '@graphql-tools/schema'; import { loadSchema } from '@graphql-tools/load'; // schema is `GraphQLSchema` instance const schema = await loadSchema('schema.graphql', { // load from a single schema file loaders: [ new GraphQLFileLoader() ] }); // You can add resolvers to that schema const schemaWithResolvers = addResolversToSchema({ schema, resolvers: { Query: {...} } });

This loader also supports glob pattern;

import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader' import { loadSchema } from '@graphql-tools/load' const schema = await loadSchema('graphql/**/*.graphql', { // load files and merge them into a single schema object loaders: [new GraphQLFileLoader()] })

If you use loadDocuments, it gives you an array of document source objects;

import { loadDocuments } from '@graphql-tools/load' import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader' const documents = await loadDocuments('graphql/**/*.graphql', { // load files and merge them into a single schema object loaders: [new GraphQLFileLoader()] })

This loader only supports Node environment because it relies on File System of your platform.

JSON File Loader#

This loader handles schema introspection and document nodes in .json files.

Introspection is handled in the example below;

import { loadSchema } from '@graphql-tools/load' import { JsonFileLoader } from '@graphql-tools/json-file-loader' import { addMocksToSchema } from '@graphql-tools/mock' const schema = await loadSchema('schema-introspection.json', { loaders: [new JsonFileLoader()] }) // Mocked non-executable schema generated from an introspection const mockedSchema = addMocksToSchema({ schema })

This loader handles json files if they represent DocumentNode, and returns an array of document sources.

import { loadDocuments } from '@graphql-tools/load' import { JsonFileLoader } from '@graphql-tools/json-file-loader' const documents = await loadDocuments('**/*-document.json', { loaders: [new JsonFileLoader()] })

This loader only supports Node environment because it relies on File System of your platform.

Code File Loader#

This loader extracts GraphQL SDL string, exported GraphQLSchema and DocumentNode from TypeScript and JavaScript code files. Let's say you have the following code file;

const ME_QUERY = gql` query Me { me { id name username age } } `

And the following code will extract Me query operation from that code file without executing it using GraphQL Tag Pluck. It understands /* GraphQL */ magic comment and gql literals. You can configure GraphQL Tag Pluck using pluckConfig.

import { loadDocuments } from '@graphql-tools/load'; import { CodeFileLoader } from '@graphql-tools/code-file-loader'; const documents = await loadDocuments('./src/**/graphql/*.ts', { loaders:[ new CodeFileLoader() ], pluckConfig: { ... } })

You can also load your schema from code files like below;

import { GraphQLSchema } from 'graphql'; // typeDefs.ts export const typeDefs = /* GraphQL */ ` type Query { foo: String } ` // or schema.ts export const schema = new GraphQLSchema(...);

This loader only supports Node environment because it relies on File System of your platform.

NOTE: If you are using typescript and path aliases, you may also need tsconfig-paths. Further reading can be found at the GitHub issue.

URL Loader#

This loader generates (a fully executable remote schema using @graphql-tools/wrap) from a URL endpoint.

import { loadSchema } from '@graphql-tools/load' import { UrlLoader } from '@graphql-tools/url-loader' const schema = await loadSchema('http://localhost:3000/graphql', { loaders: [new UrlLoader()] })

You can provide custom headers, HTTP method and custom W3C fetch method.

import { loadSchema } from '@graphql-tools/load' import { UrlLoader } from '@graphql-tools/url-loader' const schema = await loadSchema('http://localhost:3000/graphql', { loaders: [new UrlLoader()], headers: { Accept: 'application/json' }, method: 'POST', fetch: myFetch })

This loader supports both browser and node environments.

In browser this remote schema can be called using vanilla GraphQL-js and act like a simple GraphQL client.

import { loadSchema } from '@graphql-tools/load' import { UrlLoader } from '@graphql-tools/url-loader' import { graphql } from 'graphql' const schema = await loadSchema('http://localhost:3000/graphql', { loaders: [new UrlLoader()] }) const response = await graphql( schema, /* GraphQL */ ` { foo { bar { baz } } } ` ) console.log(response)