Announcing Create-GraphQL

A command-line utility to build production-ready servers with GraphQL.

Lucas Bento
Entria
4 min readNov 30, 2016

--

Create-GraphQL (https://github.com/lucasbento/create-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
Create-GraphQL init command.

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"
}
}

What's next?

I built Create-GraphQL to help us to develop faster and better, I am really looking forward to hear about enhancements and features that we can all include, these are the ones that I'm looking to work on soon:

  • Provide plugins for WebStorm and Atom to run Create-GraphQL through the IDE.

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! ❤

--

--

Lucas Bento
Entria
Editor for

Software Developer at NonDutch — building amazing apps with #react, #reactnative, #relay, #webpack, #graphql & #koa