The source code of the video examples are available here
:::danger Note: This blog post refers to an outdated version, please check http://graphql-code-generator.com/ for the latest docs! :::
About a year ago, I started writing code and apps using GraphQL.
Doing that, while coming from a production and Enterprise background, I looked for the tools available on the GraphQL ecosystem and compared it to the tools I used back then.
There were a few code generators out there, but immediately I was missing a tool that is similar to the Swagger code generator. Also, the possibilities GraphQL gives us are much greater than Swagger so I knew there was a big opportunity here.
So I started writing the code-generator for GraphQL, and I used my years of experience with Swagger code generator as inspiration.
The magic behind every good code generator, is the ability to change and extend the results quickly, while maintaining a simple (yet flexible) data structure based on your GraphQL schema and documents.
Code generators are also good for wrapping your data layer with a consistent code — for example, you can generate a function that executes the GraphQL document through your network interface, fetches the data and returns the response wrapped in a custom structure.
Typings — So yes, of course you can generate Typescript and Flow typings, Swift, Java and C#.
But the thing is, that it's much easier to add or change those generators, in fast, creating the Flow codegen took 10 minutes!
And that means that you don't need to rely on us to create the generator that you need — you can create your own custom generator in a matter of minutes and share it with the whole community!
Generate your backend — From your GraphQL definitions, you can generate your backend code! You can generate your resolvers, your data models, query builders, mutations, filters and more! Now maybe you can understand what the GraphQL Backend as a service platforms are doing… exactly that! So you can use the GraphQL-First approach and generate a full functioning backend from just your GraphQL schema! But there is a big difference — it's completely open source, you can generate just parts of it and write your own custom code or even change the templates! So you generate backend can be Node, Typescript, .NET, Java, Ruby, Python or anything you wish! And you can learn from the other community generators from other languages.
This is just the start and there is much more to explore, but we are already using it for a few production apps (for example Schneider-Electric's new online management platform), generating from a GraphQL schema with decorators a complete Mongoose ORM models with Typescript for the whole app! (the generator's templates are available here, and soon will be available as part of the built-in generators!)
In the next weeks we will release more generators and templates using SQL ORMs, but we would love to hear your use cases and to see which generators the community will come up with.
Generate REST APIs — You can use your GraphQL Schema to generate Swagger definitions and then in turn generate full functional, completely documented REST APIs without the need to maintain, support and update them!
Generate your frontend — This is sometimes less useful, but can be very helpful for generic admin panels or specific generic React components. We've already done that as well, creating a full React Material admin template that is being completely generated from a GraphQL schema. The nice thing is that we've made it so that when you edit the template it feels just like you are editing regular React code with regaulr IDE support.
Add your own — Can you think about another use case? Suggest it on our Github repo and let's try to create a template for it.
Relations to other tools and prior art:
To get started with the GraphQL code generator, start by installing NodeJS, and then install:
npm install graphql-code-generator
Then, make sure that your GraphQL schema is available for use — either in JSON file or development server.
Also, make sure your GraphQL documents are inside .graphql or .graphqls files (you don't have to, you can also put in JavaScript files with graphql-tag
package, and the generator will find it automatically!).
Now, run the generator with your config (this example uses remote GraphQL server with local GraphQL documents, and generates TypeScript typings to ./types/ directory):
gql-gen — url http://localhost:3010/graphql — template typescript — out ./types/graphql-typings.d.ts “./src/**/*.graphql”
That's it! your schema and documents are now TypeScript typings! and you won't see any IDE or linter error when using GraphQL!
This code generator can also generate only the server side schema — so you can use it in both client and server!
As time went by, I noticed that there are more GraphQL developers that struggle with the same issue — development environments such as Swift does not play along with JSON, and need to have data structures (structs) defined in order to get a better experience (otherwise, you have to treat you data as a dictionary).
I created more templates, and at the moment there are generators for the following:
BTW — We are looking for more GraphQL developers which use different environments in order to add more generators and support those GraphQL communities — for example, someone from the community is already working on a C# template.
First, we start with the GraphQL schema defined in our server-side, and try to understand it's structure and the links between the types and scalars (called GraphQL introspection query), then we modify the structure of this metadata into a custom structure that will later be simple to use.
Now, we need to use a code template (usually based on a template engine, such as Handlebars.js or Mustache), and compile it with the data structure we created earlier.
Let's take the following GraphQL schema:
type Person {
name: String
age: Int
}
The code generator transforms this definition into a custom JSON data structure, for example:
{
"models": [
{
"name": "Person",
"fields": [
{
"name": "name",
"type": "string",
"required": true
},
{
"name": "age",
"type": "number",
"required": false
}
]
}
]
}
Now, we have a generic JSON structure, and if we want to turn our schema into TypeScript type definition, we need to compile it with the following template:
{{#each models}}
export type {{name}} = {
{{#each fields}}
{{name ~}} {{#unless required ~}} ? {{~ /unless ~}} : {{ type }};
{{/each}}
}
{{/each}}
Now when we use the two together, we will get:
export type Person {
name: string;
age?: number;
}
This is a simple example, because in real life, GraphQL allows use to do much more in our schema: define enums, custom scalars, unions, interfaces, custom directives, add arguments in each field, and more.
Now let's take in to the next level — because GraphQL schema isn't everything GraphQL has — in our client side, we define our Query, Mutation, Subscription and Fragment, along with directives, arguments and more — those are called documents.
The idea is basically the same: we take the client side documents, transform it into a simple structure, then compile it with a template.
The code generator is a CLI util, written in TypeScript and NodeJS, that every developer can use, regardless the environment or the language in use.
Using graphql
npm package, I was able to load the schema and execute Introspection query, then recursively iterate over the types and links, and define a custom structure for the Models.
Then, do the same for client side documents, while assisting the server side schema to understand the types (the full custom structure is here).
The trick in client side documents is to create the correct selection set object, in each document.
For example, when using this schema:
type Person {
name: String
age: Int
}
type Query {
me: Person
}
And your query is only for the name field:
query myQuery {
me {
name
}
}
We want to generate a new type, called MyQuery_Me which based on the server side type Person, but only with the fields we wanted — name.
So while building the custom structure, we use a config flag called flatten per each language, because there are languages that allows us to flatten the inner types we just explained, and group them all together (for example, TypeScript allows you to create module or namespace, but in Swift, you have to create a recursive structs).
The next step is to implement the template for for server side and client side, the template engine I picked is Handlebars.js because it comes with a set of great template utils (such as each, if and unless), but allows you to create a custom helpers — and this is a feature I wanted to preserve and allow other developers use when creating custom templates — so each language template can implement it own template, config and template helpers!
Also, with Handlebars.js you can create a partial templates and use them inside each other, so you can easily create a recursive template to load itself — which it very useful when dealing with infinite inner-types (exactly what's GraphQL has)
I'm very excited about this release.
The graphql code-gen has come a long way and is used in many production apps, both from our users and our clients.
But it's just the beginning! Please join our community and feel free to contact me directly for any question or help you might need.
Want to hear from us when there's something new? Sign up and stay up to date!
By subscribing, you agree with Revue’s Terms of Service and Privacy Policy.
Recent issues of our newsletter