GraphQL, Schema, Extend

How to split the GraphQL schema definition into multiple files

A short guide on how to split a GraphQL schema definition into multiple files to make them more manageable.

Author Simon
Simon29th July 2022

GraphQL is a great tool for creating complex and data-rich APIs. It allows your client to request only the exact information they need, thus avoiding oversupply or undersupply.

However, anyone who has worked with GraphQL knows that the schema.graphql can grow very quickly with your application. Making the schema harder to read and maintain.

In this article, we will take a look at a solution to this problem.

Note: This article describes a solution using the extend functionality of GraphQL. This functionality is part of the GraphQL standard, but not all server frameworks support it.

Everything in one file

Our example application is a simple book API that allows you to create and read books.

A traditional schema file for such an application could look like this:

1schema {
2  query: Query,
3  mutation: Mutation
4}
5
6type Query {
7  getBook(id: Int): Book
8  getAuthor(id: Int): Author
9}
10
11type Mutation {
12  createBook(name: String, authorId: Int): Book
13  createAuthor(name: String): Author
14}
15
16type Book {
17  id: Int!
18  name: String!
19  authorId: Int!
20}
21
22type Author {
23  id: Int!
24  name: String!
25}
26

Generally, you put all your domain queries, mutations, type definitions, etc. in one file. If your project is small, this approach works fine. However, as your project grows, this file can grow quickly and become quite difficult to maintain.

Fortunately, there is a way to split schema files into multiple files. Namely with the extend keyword.

Splitting it up

With the extend keyword you can extend types. So the idea is to define the query and the mutation type in the root schema and extend them in the individual domain files.

1extend type Data {
2}
3

To implement this in our example, we create two additional files, book.graphql and author.graphql, next to our schema.graphql. In these two files, we can now extend the query and/or mutation type and move all the corresponding actions and types in there.

Here is our complete example:

schema.graphql

1schema {
2  query: Query
3  mutation: Mutation
4}
5
6type Query {
7}
8
9type Mutation {
10}
11

book.graphql

1extend type Query {
2  getBooks: [Book]!
3}
4
5extend type Mutation {
6  createBook(name: String!, authorId: Int!): Book
7}
8
9type Book {
10  id: Int!
11  name: String!
12  authorId: Int!
13}
14

author.graphql

1extend type Query {
2  getAuthors: [Author]!
3  getAuthor(id: Int): Author
4}
5
6extend type Mutation {
7  createAuthor(name: String!): Author
8}
9
10type Author {
11  id: Int!
12  name: String!
13}
14

Notes: You can leave the query and mutation in the root schema empty as long as they have been extended at least once somewhere.

Using this method, we have been able to reduce the complexity of schema.graphql definitions in several projects by splitting them into several easy-to-maintain, domain-specific files.