Automatically Generate TypeScript Definitions for GraphQL Queries with Apollo Codegen
👋🏽 Hi! I’m Faraz, and I’m a software engineer @ AdHawk.
Recently, I’ve started to use TypeScript with Apollo and React, and I’d love to share something cool that I learned.
Apollo has a great set of command line tools that make generating type definitions for your queries quite simple. This gives you the power of type checking your queries wherever you use them! Let’s dive right in.
Setup
Let’s create a new React application that uses TypeScript.
npx create-react-app react-apollo-typescript --typescript
Sweet. Now, we need to install some dependencies that we will use to generate our types and use GraphQL queries in our app.
yarn add graphql apollo-boost react-apollo
graphql
is needed for certain features, like parsing GraphQL queries. apollo-boost
comes with a well configured ApolloClient
so we can get started quickly. react-apollo
gives us components and utils we can use in React.
We will also need the apollo
command line tool and types for the graphql
package, which we can install as a devDependencies.
yarn add -D apollo @types/graphql
We have what we need to get started.
Downloading Our GraphQL Schema
In order for apollo
to generate types for our queries, we will need to download a schema of our GraphQL API and save it in a file located in our app.
For the sake of brevity in this tutorial, I’m going to be using https://graphql-pokemon.now.sh/ (and also because Pokemon are dope).
All we need to do to download our schema is:
yarn run apollo schema:download --endpoint=https://graphql-pokemon.now.sh/ graphql-schema.json
Let’s break down what’s happening here.
apollo
is the command line tool we installed in the previous step. schema:download
is the command used to download our schema into a file locally. --endpoint
is, like it says, the endpoint of our GraphQL API. If you have a local graphql server on something like http://localhost:4000/graphql
make sure that your server is running, because schema:download
actually makes a POST
request to the server. Finally, graphql-schema.json
is the name of the file we will use to store our schema.
You should see the following in your terminal:
✔ Loading Apollo Project
✔ Saving schema to graphql-schema.json
Great 🎉
If you open your project directory, you’ll see the newly created graphql-schema.json
as well.
Creating a GraphQL Query and Generating Type Definitions
Next, we will write a query so that we can retrieve some data about Pokemon. We will also generate the types for this query automatically with the apollo
cli.
I created a new query located at src/queries/pokemonsQuery.ts
It looks like this:
I’m simply querying for the $first n
number of Pokemon.
Now for the magic 🌟
yarn run apollo codegen:generate --localSchemaFile=graphql-schema.json --target=typescript --includes=src/**/*.ts --tagName=gql --addTypename --globalTypesFile=src/types/graphql-global-types.ts types
Phew. There’s a lot there. Let’s break it down.
apollo
is the command line tool, codegen:generate
is the command we use to generate the types. --localSchemaFile
is the location of the schema file we downloaded in the last step. --target
is the target we want to generate types for. We’re using typescript
, but you can do flow or swift too! --includes
is the glob of files to search for GraphQL queries. --tagName
is the name of the template literal tag that contains our queries. --addTypename
automatically adds __typename
to our queries. --globalTypesFile
by default TypeScript will add a file called “globalTypes.ts”, this overrides the file name and location. Finally, types
is the name of the folder where we want our generated types to be.
After running the command, you should see the following in your terminal:
✔ Loading Apollo Project
✔ Generating query files with 'typescript' target - wrote 2 files
And you should see the generated types in src/queries/types
🙌🏽
Using Our Typed Query in React
We now have a GraphQL query pokemonsQuery.ts
and have generated types for it.
Let’s use everything we’ve learned and create a simple React component that renders a list of Pokemon.
There’s a little bit of configuration we need to do before we can use queries within our app.
Since we used create-react-app
we need to add a few things to our tsconfig.json
First, we added some options for lib
, and exclude
our generated graphql-global-types.ts
file and the node_modules
directory.
We can now create an instance of ApolloClient
in our index.tsx
and setup our app to use it.
Editing our index.tsx
…
Thanks to apollo-boost
and react-apollo
this is all we need to do to be able to use GraphQL queries in React!
Finally, we can use the PokemonsQuery
in our App.tsx
and render a list of Pokemon!
If you noticed the comment above, this code will throw an error. first
is expected to an integer, and we are passing a string. Win.
Simply change the string ‘10’ to 10
and you should see a list of Pokemon on the screen!
Link to repo: https://github.com/faahmad/react-apollo-typescript