Type-Safe GraphQL Servers 🔎
Tags: graphql, typescript
Published: 2019-08-09 11:54:40

This post exhibits the motivations & steps for adding Type-Safety into GraphQL Servers 🎆

![](https://cdn-images-1.medium.com/max/3200/1*Ru_buRxF7Cyk_RdJ5frVSg.png)

## TL;DR
> # 👉 [The Repo & The API & The Docs & The Everything](https://codesandbox.io/s/yv004pqnq9)👇

{% codesandbox yv004pqnq9 %}

### Why should I add type-safety to my codebase?

Types enable developers to use highly-productive development tools and practices like **static** checking and code refactoring when developing JavaScript projects.

Building large scale applications, a static type checker can help safeguard your program, as well as helping you to eliminate existing errors (typos, misspellings, etc). TypeScript and Flow are both fantastic ways to limit technical debt in your JavaScript codebases, because folks,
> # JavaScript is DIFFICULT 🔥

At the same time it might be the best programming language to *start with,* since it doesn’t require to install and configure, but it doesn’t mean that it’s really **hard** to master and definitively, **error prone**!

JavaScript being **weakly** typed (in addition to being *dynamically* typed) poses a lot of problems. Note that a language is either statically or dynamically typed, let’s compare the differences between them.

### Static 💥 Dynamic Typed

**Static**
A language is **statically typed** if the type of a variable is known at **compile-time**. For some languages this means that you as programmer must specify what type each variable is (e.g.: Java, C, C++).

**Dynamic**
A language is **dynamically typed** if the type is associated with **run-time** values. This means that you as programmer can write a little quicker because you do not have to specify types every time (e.g.: JavaScript, Python, Perl)
> # Remember❗️
> # Static 👉 Compile-Time 👉 Java
> # Dynamic 👉 Run-Time 👉 JavaScript

Speaking of these languages, in order to clarify their similarities, I’ve gotta mention one of my favorite JavaScript quotes written at the hands of the author of [You Don’t Know JS](https://github.com/getify/You-Dont-Know-JS) saga (which I 💯 recommend to read):
> “JavaScript is as related to Java as Carnival is to Car.” — [Kyle](undefined) Simpson

Definitely, they do not look alike. Let’s put focus on the most popular dynamically typed language…

![Your 😑when you’re trying for 1st time JS coming from statically typed languages](https://cdn-images-1.medium.com/max/2000/1*yerQrnhxecQaJNQ1EIrXmg.png)*Your 😑when you’re trying for 1st time JS coming from statically typed languages*

Note that a language can be *dynamically* typed but also **strongly** typed, thus producing a much better language. How we could do that in JavaScript?

## Type-Safety in JavaScript

Let’s review the most known tools for adding static typing into our JS codebases!

### TypeScript

***Typed superset*** of JavaScript that compiles to plain JavaScript on any browser, any host & any OS.
[**Microsoft/TypeScript**
*TypeScript is a superset of JavaScript that compiles to clean JavaScript output. - Microsoft/TypeScript*github.com](https://github.com/Microsoft/TypeScript)

**Pros & Cons**
👌 Community & Tooling
👍 Sub-second response times
👎 Learning curve

### Flow

Static ***type checker*** for your JavaScript code. It does a lot of work to make you more productive, making you code faster, smarter, more confidently, and to a bigger scale.
[**Facebook/Flow**
*Adds static typing to JavaScript to improve developer productivity and code quality. - Facebook/Flow*github.com](https://github.com/facebook/flow)

**Pros & Cons**
👌 Out-of-the-box utility
👍 Zero config
👎 Slower and buggier

### TypeScript vs Flow

No matter if you are using TypeScript or Flow be aware of **you’re not writing plain JavaScript. **TypeScript implements both a *type checker* and a *transpiler* that emits plain JavaScript. Flow only does *type checking* and relies on [*Babel](https://babeljs.io/)* (or other tools) to remove type annotations.

If you’d like to know more about the differences regarding syntax and usability, I totally recommend to read [this comparison](https://github.com/niieani/typescript-vs-flowtype)!

In this post we will use [**TypeScript](https://github.com/Microsoft/TypeScript)** in our examples, it has better support for type generation that we’ll need later on.

## GraphQL as API

GraphQL is well know for being a strongly-typed specification for building APIs, it comes with a lot of benefits and we should take advantage of them.

Whether you’re following a *Schema-First *or* Resolver-first *approach, you’d love to end up having a **Single Source of Truth **with which develop an *End-to-end Type-Safe Application*.

Avoiding manual static typing because it can get too time-consuming as well as hard to keep in sync through versions, we might want to **auto-generate** all our types based on that *Single Source of Truth*.

In this post we’ll use the** Schema-First** approach, thus the static types will be generated based on our *GraphQL Schema *instead of from our resolvers!

In order to remove friction between type definitions we might introduce automation. Here is where the **GraphQL Types Generators** come in!

## GraphQL Types Generators

Let’s review the most known tools for auto generating types based on our GraphQL Schema.

### GraphQL Code Generator

Tool that generates different types code outputs of your GraphQL Schema & Documents whether you are developing client, server or database.
[**GraphQL Code Generator *Generate code from your GraphQL schema with a single function call***
graphql-code-generator.com](https://graphql-code-generator.com/)

**Pros & Cons**
👌 Client, Server & DB support
👍 Docs & Community
👎 Early stage of development

### **GraphQLGen**

Generate & scaffold type-safe resolvers based on your GraphQL Schema in TypeScript, Flow & Reason.
[**GraphQLGen**
*Programming in type-safe environments provides a lot of benefits and gives you confidence about your code*oss.prisma.io/graphqlgen/](https://oss.prisma.io/graphqlgen/)

**Pros & Cons**
👌 Defaults resolvers generation
👍 Integrable with Prisma
👎 Only Server support

### **GraphQL Code Generator vs GraphQLGen**

Both are great for generating *TypeScript* & *Flow* types although **GraphQLGen** doesn’t provide you the ability to generate them for the Client. Instead, **GraphQL Code Generator** does, also it provides you a tons of plugins/configurations & the possibility to create your custom type generation templates. I found out this really useful in order to have a modular GraphQL Schema configured as you wish!

In this post we will use [**GraphQL Code Generator](https://graphql-code-generator.com) **in our examples, it has better customization that we’ll need later on.
> # Ok, I know, too much theory…

![](https://cdn-images-1.medium.com/max/2000/1*lBgPeLa4sfAqKw8Bj9OpKA.gif)
> # … let’s set this up 🚀

## Setup [TypeScript](https://github.com/Microsoft/TypeScript)

![[TypeScript](https://typescriptlang.org) main features](https://cdn-images-1.medium.com/max/2552/1*F9SdgWKARE5TFVwZQ2JZSw.png)*[TypeScript](https://typescriptlang.org) main features*

### **Install it**

    yarn add -D typescript

### **Install Run libraries**

In order to execute TypeScript with Node, you have to add the following tools:

[*TS-Node](https://github.com/TypeStrong/ts-node)*: TypeScript execution and REPL for Node.js, with source map support.
[*Nodemon](https://github.com/remy/nodemon)*: Monitor for any changes in your Node.js application restarting automatically the server.

    yarn add -D ts-node nodemon

You might want to use other configuration, setup whatever fits better for your app!

### Include @types

Add your *high quality* type definitions of the libraries that you’re currently using over your codebase, such as graphql, lodash, etc. If you’re 🤨 about this, check the [*DefinitelyTyped docs](http://definitelytyped.org/)*!

    yarn add -D @types/graphql

### **Create TypeScript config**

This way TypeScript will include *all* the .ts files in your directory (and sub directories) as a part of the compilation context. It will also select a few sane default compiler options, you could check them out [here](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html)!

    **// tsconfig.json
    **{
      "compilerOptions": {
        "target": "esnext",
        "module": "commonjs",
        "moduleResolution": "node",
        "sourceMap": true,
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "esModuleInterop": true
      },
      "include": ["src/**/*"],
      "exclude": ["node_modules", "dist", "**/*.spec.ts"]
    }

### **Create Run config**

*Nodemon* supports local configuration files located in the current working directory where you have to specify things like which **path to watch** & the command to execute after any reload, which is your server. Check the [sample config](https://github.com/remy/nodemon/blob/master/doc/sample-nodemon.md)!

    **// nodemon.json
    **{
      "watch": ["src"],
      "ext": "ts",
      "ignore": ["src/**/*.spec.ts", "src/types/**/*.d.ts"],
      "exec": "ts-node ./src/index.ts"
    }

### **Add Run config**

    **// package.json
    **{
      ...
      "scripts": {
        ...
        "start": "nodemon",
        ...
      }
      ...
    }

## **Rename .js files 👉 .ts**

Modify all your JavaScript filename extensions to .ts, it’ll allow you take advantage of the all TypeScript features

### Test your app

Run your *GraphQL Server*, as JavaScript is 100% compatible with TypeScript (not the opposite, TS types are not allowed on JS compilers), it should work!

    yarn start

### Weeding out Errors

It’s not unexpected to get error messages after conversion. The important thing is to actually go one by one through these and decide how to deal with the errors. Often these will be legitimate bugs, but sometimes you’ll have to explain what you’re trying to do a little better to TypeScript. Don’t hesitate to check this [migration guide](http://www.typescriptlang.org/docs/handbook/migrating-from-javascript.html) for help to fix the possible errors!

## **Setup [GraphQL Code Generator](https://graphql-code-generator.com)**

![[GraphQL Code Generator](https://graphql-code-generator.com) main features](https://cdn-images-1.medium.com/max/2876/1*Jw_S5yw_Jsi7cMIXXD8B4Q.png)*[GraphQL Code Generator](https://graphql-code-generator.com) main features*

### **Install it**

    yarn add -D graphql-code-generator

### **Install Plugins**

We’ll setup the *common*, *server* & *resolvers TypeScript *plugins, you might want to use others, check the [plugins available](https://graphql-code-generator.com/docs/plugins/)!

    yarn add -D graphql-codegen-typescript-common graphql-codegen-typescript-server graphql-codegen-typescript-resolvers

### Create Context type

If you wish to use a custom type for your GraphQL *context *and* *you don’t want to specify it each time that you declare your resolvers, you can create it manually and add it to the* run config* file (as we’ll do it in the next step):

    **// types/context.d.ts
    **export type MyContext = {
      db: any;
      find: any;
      limit: any;
      order: any;
      project: any;
      sort: any;
    };

**Create Run config**

The CLI will automatically detect the defined config file and will generate code accordingly, you could check the available options [here](https://graphql-code-generator.com/docs/getting-started/codegen-config)!

    **// codegen.yml***
    *schema: src/schema/**/*.ts
    overwrite: true
    watch: true
    require:
      - ts-node/register
    generates:
      ./src/types/types.d.ts:
        config:
          contextType: ./context#MyContext
        plugins:
          - typescript-common
          - typescript-server
          - typescript-resolvers

### Add Run config

    **// package.json
    **{
      ...
      "scripts": {
        ...
        "generate": "gql-gen",
        ...
      }
      ...
    }

## Generate Types ⚙️

Everything is setup for getting our desired static types 😍, let’s make that happen!

    yarn generate

## Add Resolver Types!

Now, you just have to include your *TypeScript *generated static types into your *GraphQL Resolvers *as here

![Adding TypeScript types into GraphQL Resolvers & 🔎the Resolvers Data Types](https://cdn-images-1.medium.com/max/2000/1*YDeNWttazokA3eh4sYhwHg.gif)*Adding TypeScript types into GraphQL Resolvers & 🔎the Resolvers Data Types*

![It’s not 😂, take a look to your types.d.ts generated!](https://cdn-images-1.medium.com/max/2000/1*mPUc2fU1VPbW6gjbw1DjeQ.gif)*It’s not 😂, take a look to your types.d.ts generated!*

## Recapping

In order to add *Type-Safety* into your GraphQL Server using *Schema-First* approach you could:

⚫ Setup TypeScript
↳ Install TypeScript, run libraries & @types
↳ Create TypeScript config & run config
↳ Add run config
⚫️ Rename .js 👉.ts files
⚫️ Setup GraphQL Code Generator
↳ Install GraphQL Code Generator & plugins
↳ Create context type & run config
↳ Add run config
⚫️ Generate Types ⚙️
⚫️ Add Resolver Types!

## 👀 the benefits

Discover some of the use cases where you’d take advantage of using *TypeScript *together with *GraphQL*!

### Evolve your schema

{% twitter 1080137523190468608 %}

### 🔎 the arguments

{% twitter 1080137527439314944 %}

### Catch Misspellings

{% twitter 1080137530320797696 %}

### 🔎 the context

{% twitter 1080137533319720962 %}

### Discover your data

{% twitter 1080137536507465729 %}

## The Future

In order to talk about what the new era holds 😬, you cannot miss the motivations for which GraphQL was created, [Dan Schafer](undefined) resumed them perfectly 👇

{% youtube 6NYC-k2Abow %}

Schema💥Resolver First approach,
Types💥Classes/Decorator generators,
Readability💥Composability,

… 2019 aims to be busy for GraphQL 😅,
read the first impressions about its future,
it’s as exciting as overwhelming,
but really, don’t miss it, 💯 thread!

{% twitter 1080400713770024960 %}

![](https://cdn-images-1.medium.com/max/3840/1*f6IMUipNmjSrEp9iEAX4sw.jpeg)

I’ll be following this post up 🔜 with the respective **Type-Safe GraphQL Clients** 🔎 post, stay tuned!

Please, consider🙏🏻ing, contribut♻️ing and shar💜ing it!