Modularize and decouple GraphQL schema and resolvers.
$ npm install --save graphql-schema-modules
- Keep different query/mutation/subscription definitions in separate files
- Keep resolvers and GraphQL definitions modularized
- Load GraphQL from directory
graphql/shared.js
export const typeDefs = `
enum UserType { MEMBER, ADMIN }
type schema {
query: Query
mutation: Mutation
}
`;
graphql/users.js
export const typeDefs = `
type User {
id: Int!
type: UserType!
}
input UserInput {
type: UserType!
}
input UserFilters {
type: UserType
}
type Query {
user: User!
users (filters: UserFilters = {}): [User!]!
}
type Mutation {
userCreate (input: UserInput!): User!
}
`;
export const resolvers = {
Query: {
async user () {
return { id: 1, type: 'MEMBER' };
},
async users () {
return [];
},
},
Mutation: {
async userCreate () {
return { id: 1, type: 'MEMBER' };
},
},
};
graphql/posts.js
export const typeDefs = `
type Post {
id: Int!
title: String!
}
input PostInput {
title: String!
}
type Mutation {
postCreate (input: PostInput!): Post!
}
type Query {
posts: [Post!]!
}
`;
export const resolvers = {
Mutation: {
async postCreate () {
return { id: 1, title: 'Post1' };
},
},
Query: {
async posts () {
return [];
},
},
};
buildSchema.js
import { mergeModules, loadModules } from 'graphql-schema-modules';
import { makeExecutableSchema } from 'graphql-tools';
import * as shared from './graphql/shared.js';
import * as posts from './graphql/posts.js';
import * as users from './graphql/users.js';
const { typeDefs, resolvers } = mergeModules([ shared, posts, users ]);
// OR
// const { typeDefs, resolvers } = loadModules(__dirname + '/graphql');
console.log(typeDefs[0]);
const schema = makeExecutableSchema({ typeDefs, resolvers });
export default schema;
The output will be:
type Post {
id: Int!
title: String!
}
input PostInput {
title: String!
}
# This is where magic happens - mutations are merged
type Mutation {
postCreate(input: PostInput!): Post!
userCreate(inut: UserInput!): User!
}
# This is where magic happens - queries are merged
type Query {
posts: [Post!]!
user: User!
users(filters: UserFilters = {}): [User!]!
}
enum UserType {
MEMBER
ADMIN
}
type schema {
query: Query
mutation: Mutation
}
type User {
id: Int!
type: UserType!
}
input UserInput {
type: UserType!
}
input UserFilters {
type: UserType
}