Folder/Schema Structure with GraphQL

One thing I really wanted to figure out as soon as I went throught the basics of GraphQL is whether you could separate your project schema file into several different schema type definitions files.
As you’re adding more query types to to your schema file and functions to your resolvers, you can see it slowly becoming more and more difficult to manage, and searching through a file with many lines is no fun.

So… first thing to workout is how we can separate our schema into several files and then create a folder structure to manage those files.

There’s an NPM package called graphql-tools which allows you to combine your typeDefs and resolvers and to pass to you startup file. This is really useful as it’s the first step to managing our files.

GraphQL Tools is an npm package and an opinionated structure for how to build a GraphQL schema and resolvers in JavaScript, following the GraphQL-first development workflow.

We have a way of combining the schema and resolvers, next we have to split those files into more specific schema-type files.

For example, you have a User type with queries and resolvers which handle user data. In the same file you have a Role type which also has its own queries and resolvers.
Let’s split them into individual schema related files, , , , .

I will show you how I am organising my GraphQL project files and folders currently.

root/
- .devcontainer/
- config/
- services/
- src/
- db
- helpers
- data-loaders
- middleware/
- schema/
- role/
- index.js
- role.resolvers.js
- role.types.js
- user/
- index.js
- user.resolvers.js
- user.types.js
- index.js
- index.js
- package.json
...

Here is how you combine each file merge them together in the main schema export file. The property accepts an array of strings and the resolvers require the package to merge.

~/src/schema/index.js

Now use it like this,

const schema = require('./src/schema')app.use('/graphql', graphqlHTTP(req => ({    
schema,
graphiql: true,
...
}))

Note:- The first file in the array is the standards syntax, like so

type Query {        
login(input: UserLogin!): String
users: [User]
user(id: ID!): User
}

Each subsequent file in the array requires you to extend the Query type, like this,

extend type Query {        
roles: [Role]
userRoles: [UserRole]
}

So there you have it!

This is how I’ve structured my project files and folders, however, I realise there are many approaches which suit different people. Pick the one that suits you best.

My example project on GitHub called express-graphql-api uses this folder structure.

Feedback on this approach/idea or any suggestions will be appreciated.

Happy coding!

Lead Developer. Angular. Node. GraphQL. JavaScript enthusiast.