DIV and Backend again. A TypeScript Tale: Part 4

GraphQL Code Generation

GraphQL Code Generator is the type safe link between your back end service, and your front end. This is it, Mr. Frodo, If we take one more step, we’ll be the furthest from home we’ve have ever been.


  1. Nx.dev- In Part 1, we setup an Nx workspace, with a NextJS front end.

  2. Type-GraphQL - In Part 2, we setup a graphql server that generates our graphql schema based on our types.

  3. TypeORM - In Part 3, we connected our Type-GraphQL server up to our database using TypeORM.

  4. YOU ARE HERE
    GraphQL Code Generator
    - The type safe link between your front end and your back end. We will generate an SDK, which we can use on the front end to achieve complete type safety. We will use the apollo generator, but there are tons of options for common graphql tooling.

  5. Tying it all together - Lets put all our hard work to good use with some examples.

Prerequisites

You should have the following installed:

  1. Part 1 - Nx

  2. Part 2 - type-graphql.

  3. Part 3 - TypeORM

  4. node: version 14 or greater. I recommend NVM if you need to switch versions between projects.

  5. yarn: You could use npm if you like, but this guide will be using yarn in it’s examples.

  6. Docker: We use docker to setup a development database. You can always install postgres directly on your machine if you don’t want to use Docker. Just make sure postgres is running on port 5432.

Part 4: Generating our Apollo Hooks using GraphQL Code Generator

Want to skip ahead? Check out the the Part 4 source on GitHub

The hard part is over, now it’s time to reap our benefits. We’ll be using GraphQL Code Generator to create all the types for the front end automatically.

As usual, we need to start by adding some dependencies:

yarn add -D @graphql-codegen/cli

Then we will create a library for all things generated. Lets call it: graphql-sdk.

nx generate @nrwl/node:library --name=graphql-sdk --unitTestRunner=none --no-interactive

Go ahead and delete libs/graphql-sdk/src/lib/graphql-sdk.ts, since we won’t be using that file at all.

Create a new file libs/graphql-sdk/src/lib/myLists.gql and add the following query:

Now we can initialize the code generator:

yarn graphql-codegen init

When asked about your project:

  1. What type of application are you building? Application Built With React

  2. Where is your schema? http://localhost:3333/graphql

  3. Where are your Operations and fragments? libs/graphql-sdk/src/lib/**/*.gql

  4. ¹Pick Plugins: TypeScript React Apollo

  5. Where to write the output: libs/graphql-sdk/src/lib/graphql-sdk.ts

  6. Do you want to generate an introspection file? No

  7. How to name the config file? codegen.yml

  8. What script in package.json should run the codegen? gen-sdk

¹ There is another plugin called React Apollo Next, which may work better for you. I haven’t used it before, so I won’t be going over it here.

Next run yarn install once more, since the init command added dependencies.

All that’s left is to generate your code

yarn gen-sdk 

You can see it in action:

Using the generated code on the front end

Luckily, Nx makes this trivial.
Start by clearing out all the content in apps/web/pages/index.tsx

Instead we’ll replace it with a simple h3 tag.

Next we need to install and setup the apollo client

yarn add @apollo/client

Initialize the apollo client and set it up with react provider, and move move the list content to a component: apps/web/components/todoList.tsx

apps/web/pages/index.tsx

In apps/web/components/todoList.tsx is where all the magic is happening. I went ahead and added some basic UI, but don’t let that distract you.

As you can see, on line 2:

import { useMyListsQuery } from '@the-wooley-devbox/graphql-sdk';

we are getting useMyListsQuery from our generated sdk.

on line 4:

const { data, loading, error, refetch } = useMyListsQuery({ ssr: false });

We are using our query to get back completely typed data. We don’t have any data to check yet, but the types are strong enough, that I feel good about making a basic UI.

Lets add some data

We need to add a few mutation to create a list. Add a mutation to libs/graphql/src/lib/list/list-resolver.ts

Add the matching, mutation to libs/graphql-sdk/src/lib/myLists.gql

run yarn gen-sdk

All that’s left is using the mutation in our front end. Lets modify apps/web/components/todoList.tsx

Lets break something intentionally to see how type checking can help us. How about marking items as nullable. That way our types should tell us on the front end if we are accessing something that could be null:

libs/db/src/lib/entity/List.ts

Don’t forget to run `yarn gen-sdk`, after making the change.

Turns out, typescript isn’t warning us about null checks because we have strict set to false. Luckily that’s an easy fix. Turn on strictNullChecks in apps/web/tsconfig.json

Ok, reload your project TS project, and lets open up apps/web/components/todoList.tsx

Just what we were hoping for! Type Errors everywhere. When we made items nullable, we changed our types! Now typescript will show us that these things could be null. A few more modifications to apps/web/components/todoList.tsx, to clean up the errors. While were at it: Lets clean up that bug where “Looks like you don’t have any lists” is always showing.

Looks like everything is working now!

Up Next

Wow! Full stack Type Safety! And we did it with 1 Post to spare. In the next post, we will finish implementing our todo items, and maybe add some polish.