Announcing Create-GraphQL
A command-line utility to build production-ready servers with GraphQL.
Writing a lot of boilerplate to create common pages can be overwhelming sometimes, at @Entria we create the very same basic files every time we start a feature, after a while you notice that you can automate a bunch of processes that you do every day, that's why I created Create-GraphQL (https://github.com/lucasbento/create-graphql).
What is Create-GraphQL?
It's a simple command line utility that can initiate a whole project using GraphQL with KoaJS and generate:
- Types;
- Mutations;
- Relay Connections;
- Loaders (using Facebook's DataLoader);
- Tests (with the awesome Jest).
A very nice feature included is creating types and mutations from a Mongoose schema file, the CLI will parse the fields and generate a type and/or mutation accordingly.
Why use a CLI?
Kent C. Dodds' shares awesome views on his article An Argument for Automation, we do the same processes every single day, same with our coworkers, how much impact can we make by automating a few of our processes, especially if it's open-sourced?
Being humans, we make mistakes on repetitive tasks, even the most common ones. Those errors would be greatly reduced by simple automated processes.
How to use it?
First install it through npm
:
npm install --global create-graphql
Then you can start using it, to see all the available commands, simply type:
create-graphql --help
To initiate a whole project, you should use init option and pass the name of the project, e.g.:
create-graphql init MyAwesomeProject
A GraphQL server will be created and installed on MyAwesomeProject folder, you can run it with the npm scripts available on its package.json
.
Available generators
Type
To generate a type, simply use:
create-graphql generate --type Awesome
A GraphQL type will be created under the folder ./src/type
.
Tip: you may change the folders that will be used by creating
.graphqlrc
file, don't worry, we will see more about that on the next parts of the article.
Mutation
Generating a mutation is as easy as a type:
create-graphql generate --mutation Awesome
A create and edit mutation will be created on the folder ./src/mutation
.
🔥 Tip: you may use the commands aliases to generate multiple files in one single command:
create-graphql generate -tm Awesome
Which will create a type and mutation with the name Awesome.
Generating from a Mongoose schema
To generate from a Mongoose schema, you just have to add the --schema
option to a --type
or --mutation
command, e.g.:
The following model:
import mongoose from 'mongoose';
const { ObjectId } = mongoose.Schema.Types;
const Schema = new mongoose.Schema({
content: {
type: String,
description: 'Comment content in the original language',
required: true,
},
user: {
type: ObjectId,
ref: 'User',
indexed: true,
description: 'User that created this comment',
required: true,
},
owner: {
type: ObjectId,
required: true,
description: 'Object that owns of this product. References to Product, Posts or other comment.',
},
}, {
collection: 'comment',
timestamps: {
createdAt: 'createdAt',
updatedAt: 'updatedAt',
},
});
export default mongoose.model('Comment', Schema);
Will produce the CommentType.js
:
import {
GraphQLObjectType,
GraphQLString,
GraphQLID,
} from 'graphql';
export default new GraphQLObjectType({
name: 'CommentType',
description: 'Represents CommentType',
fields: () => ({
content: {
type: GraphQLString,
description: 'Comment content in the original language',
resolve: obj => obj.content,
},
user: {
type: GraphQLID,
description: 'User that created this comment',
resolve: obj => obj.user,
},
owner: {
type: GraphQLID,
description: 'Object that owns of this product. References to Product, Posts or other comment.',
resolve: obj => obj.owner,
},
}),
});
And the mutation:
import {
GraphQLString,
GraphQLID,
GraphQLNonNull,
GraphQLNonNull,
GraphQLNonNull,
} from 'graphql';
import {
mutationWithClientMutationId,
toGlobalId,
} from 'graphql-relay';
import CommentLoader from '../loader/CommentLoader';
import CommentConnection from '../connection/CommentConnection';
export default mutationWithClientMutationId({
name: 'CommentAdd',
inputFields: {
content: {
type: new GraphQLNonNull(GraphQLString),
},
user: {
type: new GraphQLNonNull(GraphQLID),
},
owner: {
type: new GraphQLNonNull(GraphQLID),
},
},
mutateAndGetPayload: async ({ example }) => {
// TODO: mutation logic
return {
// id: id, // ID of the newly created row
error: null,
};
},
outputFields: {
commentEdge: {
type: CommentConnection.edgeType,
resolve: async({ id }, args, { user }) => {
// TODO: load new edge from loader
const comment = await CommentLoader.load(
user, id
);
// Returns null if no node was loaded
if (!comment) {
return null;
}
return {
cursor: toGlobalId('comment', comment),
node: comment,
};
},
},
error: {
type: GraphQLString,
resolve: ({ error }) => error,
},
},
});
To see the other available commands, check out the project GitHub on: https://github.com/lucasbento/create-graphql.
Customizing the folders
You may customize the folders that the generated files will be created on by using a .graphqlrc
file on the root folder specifying the ones that you wish to use, e.g.:
{
"directories": {
"source": "src",
"connection": "graphql/connection",
"loader": "graphql/loader",
"model": "models/models",
"mutation": "graphql/mutation",
"type": "graphql/type"
}
}
If you have any feedback, please open an issue or contact me on Twitter (@lbentosilva), I'll be glad to talk to you!
Hopefully this will be as valuable to you as it is for me! ❤