GraphQL Code Generator v0.11

Dotan Simha
GraphQL Code Generator v0.11 - The Guild Blog
Note:

This blog post refers to an outdated version, please check http://graphql-code-generator.com/ for the latest docs!

Generate React and Angular Apollo Components, Resolver signatures and much more!

We are very excited to announce a new release for graphql-code-generator!

If you haven’t checkout graphql-code-generator before, please check out the following introductory blog posts:

v0.11 holds a lot of improvements, new features and a couple of new templates, mostly in Typescript — for frontend and backend!

Here is the gist of it:

  • New React and Angular templates to greatly simplify the usage of Apollo Client and Typescript and auto-generate a lot of the current boilerplate
  • Generate types for resolvers
  • Major overall to support generation of custom scalar types
  • Support for GraphQL-Yoga with graphql-import
  • Watch mode
  • Major refactoring and improvements to the Typescript Mongo template

But the best part of all — on this release we saw a major increase in contributions and contributors! This is a strong sign for the growth of the ecosystem around graphql-code-generator.

Thank you so much everyone, we are humbled by your help. keep it coming!

Even though we haven’t decided to declare 1.0 yet, we use this library on each one of our projects and our clients projects.

Each PR merged creates an alpha release to npm which we then test out and upgrade all of those applications.

Only then we release a full npm version, so you can be assured that by time of the release, it has already been tested by major Enterprise applications who deploy daily into production, on top of all the unit tests on the project!

So all of the new features that are being mention on this post, are already being used by us extensively.

OK, let’s start with the new features for the client side Typescript users:

React templates

react-apollo recently introduced a new default API with Query, Mutation and Subscription components.

Whether you use the new API or prefer HOC and you use Typescript, there is no need to write those wrapper components again and again!

With the new TypeScript React Apollo Template, you don’t need to anymore!

All you need to do is to write your GraphQL Query, Mutation or Subscription, and the codegen will generate fully typed react-apollo components and HOC for each one.

That makes using React Apollo with Typescript so much simpler!

You can read more about it in the following blog post:

/blog/codegen-typescript-react-apollo

Thank you Arda TANRIKULU for that amazing contribution!

Angular templates

But why just React? Angular should get the same benefits!

Apollo-angular also recently added added the Query, Mutation and Subscription services.

But why writing them by yourself?

With the new TypeScript Angular Apollo Template, all you need to do is to write your GraphQL Query, Mutation or Subscription, and the codegen will generate a fully functioning, fully typed Angular service for each of those!

As this was a contribution by Kamil Kisiela, the creator and maintainer of the apollo-angular library, we believe we can endorse it from now on as the best way of using apollo-angular!

You can read more about it in the following blog post:

/blog/apollo-angular-12

Thank you very much Kamil Kisiela, the creator and maintainer of apollo-angular for that amazing contribution, from the apollo-angular and the graphql-code-generator side!

Moving on to the new backend features.

Generate types for resolvers

The TypeScript template is now able to generate Typescript types not only for a schema and documents but also for GraphQL Resolvers. And It’s enabled by default!

We think this was another missing piece of making your code even more strongly typed, from end to end.

The template now generates a Typescript type for each GraphQL type with resolvers for all of its fields but it is also possible to extract a type of a single field.

import { QueryResolvers } from './generated/graphql';
import { getPosts } from './posts';

const Query: QueryResolvers.Resolvers = {
  posts() {
    return getPosts();
  },
};

As you can see the usage is straightforward but we recommend to explore the source code of a generated file.

Custom scalars improvements

Prior this version, scalars were declared with any which means we didn’t take enough advantage of TypeScript here. This was an another opportunity to strengthen up your code. We’re happy to tell you it’s now possible to customize a scalar and provide a type instead of having it as any.

We also introduced a new option called prepend to add a code at the beginning of a generated file, it completes the custom scalars feature.

Unified naming strategy

camelCase, PascalCase, snake_case, lowercase, UPPERCASE, CONSTANT_CASE, there’s a lot of ways for people to name their types in GraphQL schema. It was a wild west, until now.

We decided to unify the naming strategy in codegen and pick just one. We chose PascalCase. And now, everything generated by codegen follows that rule.

Maybe at some point in the future, graphql-code-generator will allow to set your own naming strategy. Contributions are welcome so don’t feel afraid, we will help you!

Keep on mind that it’s a breaking change, TypeScript might warn about non existing type, if so then change it to be PascalCased.

Watch-mode

Now the GraphQL Code Generator detects changes in your schema and type definitions, and generates typings automatically after you edit these files.

The only thing you need to do is add -w parameter to the command line.

Thank you Arda TANRIKULU and FredyC for that great contribution!

Support for GraphQL-Yoga with graphql-import

Thanks to David Yahalomi’s great contribution, GraphQL Code Generator now understands the graphql-import syntax being used by GraphQL Yoga.

# import B from "b.graphql"

type A {
  # test 1
  first: String
  second: Float
  b: B
}

MongoDB Schema Template

We are also working on improving the MongoDB Typescript schema template.

We are using this template in many of our apps in production, it saves us a lot of boilerplate and potential bugs, and it’s also easier to maintain and keep track of the MongoDB schema objects.

Basically, this template let’s you generate TypeScript typings for the shape of your MongoDB objects based on your GraphQL schema.

For example, using the following schema:

type User @entity {
  id: String @id
  username: String! @column
  email: @column
}

You will get a generated TypeScript interface:

import { ObjectID } from 'mongodb';

export interface UserDbObject {
  _id: ObjectID;
  username: string;
  email?: string | null;
}

Then, you can use it with MongoDB driver for NodeJS:

import { Collection } from 'mongodb';
import { db } from './my-db-instance';

const MyCollection: Collection<UserDbObject> = db.collection<UserDbObject>(
  'users'
);

Now your MongoDB collection is typed, and it’s easier to find bugs during development.

We understand that a lot of edge cases might occur because of the differences between GraphQL schema and the lack of schema in MongoDB, so we added @map directive that lets you do custom mapping of fields:

type User @entity {
  id: String @id
  username: String! @column @map(path: "profile.credentials.username")
  email: @column
}

Will output:

import { ObjectID } from 'mongodb';

export interface UserDbObject {
  _id: ObjectID;
  profile {
    credentials: {
      username: string;
    };
  };
  email?: string | null;
}

There is also the need to handle the difference between embedded types and linked types, so you can use @entity(embbeded: true) and @embbeded to declare link and embedded entities:

type User @entity {
 id: String @id
 profile: Profile! @embedded
 email: @column
 photos: [Photo] @link
}

type Profile @embedded {
 fullName: String
}

type Photo @entity {
 id: String! @id
 url: String! @column
}

Will output:

import { ObjectID } from 'mongodb';

export interface UserDbObject {
  _id: ObjectID;
  profile: ProfileDbObject;
  photos: [ObjectID];
  email?: string | null;
}

export interface ProfileDbObject {
  fullName: string;
}

export interface PhotoDbObject {
  _id: ObjectID;
  url: string;
}

Another issue is to add fields that are relevant only for the MongoDB schema, and not relevant to your GraphQL schema (such as security token and login hashes), so you can define it in your GraphQL Schema:

type User @entity(additionalFields: [
 { path: "services.login.token", type: "string" }
]) {
 id: String @id
 email: @column
}

We also addressed GraphQL Interface and now you can use @abstractEntity to override your interfaces, and if you are using GraphQL Unions, you can add a custom @discriminatorField to your union, and it will add the field to your MongoDB schema.

We are also thinking about adding more templates for entities schemas in the future, such as JSON schema.

_We are planning to release the new version of that template next week and write a dedicated blog post on it with more details._id

Also, that template can be a great start for others to add the same generated features to other data sources like SQL and NoSQL databases, DB ORMs and more!

Other honorable mentions on this release:

Watch the complete breakdown of the releases and features here: (https://github.com/dotansimha/graphql-code-generator/releases)[https://github.com/dotansimha/graphql-code-generator/releases]

As usual, we keep all of our dependencies up to date with each release thanks to renovate. This release updates everything to latest as usual, including TypeScript 3.0.

We believe it is a good open source practice and helps not just us and our users but it also helps our open source dependencies authors to get early feedback on any issue that might happen.

Friends help friends test early! ;)

We encourage that practice on for any open source library and any application!


What other ideas do you have for generating things?

If you have any ideas or custom needs, that’s exactly where the graphql-code-generator shines, let us know about your needs and we would be happy to support you!

This version wouldn’t be possible without the great help of sgoll, David Yahalomi, Arda TANRIKULU, Kamil Kisiela, degroote22, jycouet, FredyC, prevostc, arvind-chandrashekar-ck, Cactucs.

Also want to contribute? here are some ideas for future contributions (but any ideas would be welcomed!), we would love to support and help any new contributor who want to give it a try!

Don’t forget — if you created your own template and think it could benefit others, link it on our readme here.


Star and follow us on Github and Twitter, we have a lot more coming soon!